How to align columns of multiple lines at a fixed distance with vim

text processingvim

Here is another one of my vim question (They seem to become my trademark here.).
I have a really long file basically consisting of lines of the following form:

;07     :ANZ textv      S9_1  9_1_K3_2  S9_3  S9_4 9_1_K3_5 S9_T1_1 S9_T1_2 S9_T1_3 S9_T1_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    9_V3n   E3         
;08     :ANZ textv      S9_1  9_1_K3_2  S9_3  S9_4 9_1_K3_5 S9_T1_1 S9_T1_2 S9_T1_3 S9_T2_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    9_V3n   E3  
09     :ANZ textv       S9_1  9_1_K3_2  S9_3  S9_4 9_1_K3_5 S9_T1_1 S9_T1_2 S9_T1_3 S9_T3_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    9_V3n   E3  

;10     :ANZ textv      S9_1  9_1_K4_2  S9_3  S9_4 9_1_K4_5 S9_T1_1 S9_T1_2 S9_T1_3 S9_T1_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    9_V4n   E3         
;11     :ANZ textv      S9_1  9_1_K4_2  S9_3  S9_4 9_1_K4_5 S9_T1_1 S9_T1_2 S9_T1_3 S9_T2_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    9_V4n   E3  
12     :ANZ textv       S9_1  9_1_K4_2  S9_3  S9_4 9_1_K4_5     S9_T1_1     S9_T1_2     S9_T1_3     S9_T3_4     S9_T1_5     S9_T1_6     S9_T1_7     S9_T1_8     S9_T1_9     S9_T1_10    9_V4n       E3  

13     :ANZ text    S9_1  9_2_K1_2  S9_3  S9_4  9_2_K1_5    S9_T1_1 S9_T1_2 S9_T1_3 S9_T1_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    
;14     :ANZ text       S9_1  9_2_K1_2  S9_3  S9_4  9_2_K1_5    S9_T1_1 S9_T1_2 S9_T1_3 S9_T2_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    
;15     :ANZ text       S9_1  9_2_K1_2  S9_3  S9_4  9_2_K1_5    S9_T1_1 S9_T1_2 S9_T1_3 S9_T3_4 S9_T1_5 S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    

As you can see the columns of these lines are not aligned e.g. line 13 is misaligned with respect to lines 14 and 15 because of the ;. But there are more difficult cases of misalignment. For example there are lines like this:

;14     :ANZ text   S9_1  9_2_K1_2   S9_3  S9_4 9_2_K1_5         S9_T1_1    S9_T1_2 S9_T1_3 S9_T2_4 S9_T1_5 S9_T1_6 S9_T1_7       S9_T1_8 S9_T1_9   S9_T1_10    
;15     :ANZ text           S9_1  9_2_K1_2  S9_3     S9_4   9_2_K1_5    S9_T1_1 S9_T1_2 S9_T1_3 S9_T3_4 S9_T1_5     S9_T1_6 S9_T1_7 S9_T1_8 S9_T1_9 S9_T1_10    

or whatever you can imagine. What I want is to align all columns such that between every column there are four spaces distance. For example, I want lines ;07-09 to look like this:

;07     :ANZ    textv    S9_1    9_1_K3_2    S9_3    S9_4    9_1_K3_5    S9_T1_1    S9_T1_2    S9_T1_3    S9_T1_4    S9_T1_5    S9_T1_6    S9_T1_7    S9_T1_8    S9_T1_9    S9_T1_10    9_V3n    E3         
;08     :ANZ    textv    S9_1    9_1_K3_2    S9_3    S9_4    9_1_K3_5    S9_T1_1    S9_T1_2    S9_T1_3    S9_T2_4    S9_T1_5    S9_T1_6    S9_T1_7    S9_T1_8    S9_T1_9    S9_T1_10    9_V3n    E3  
 09     :ANZ    textv    S9_1    9_1_K3_2    S9_3    S9_4    9_1_K3_5    S9_T1_1    S9_T1_2    S9_T1_3    S9_T3_4    S9_T1_5    S9_T1_6    S9_T1_7    S9_T1_8    S9_T1_9    S9_T1_10    9_V3n    E3  

Is there a way to do this with vim in an efficient way?

Best Answer

In command mode, run:

:%!column -t

But this does not align the first column. You should use Align plugin for more advance option.

Or you could format it without vim, a perl way:

perl -anle 'BEGIN{$"="\t"} $F[0] = sprintf("%3s", $F[0]);print "@{[@F]}"' file

Set $" to whatever you want for delimiter.

Related Question