user2849420
user2849420

Reputation:

Sorting on multiple columns and ignoring fields in vim

is it possible to sort on multiple columns and ignore certain lines starting with # ? I have my a text like this:

#Comments
#More comments
foo;1;1
foo;3;2
bar;2;1

I'd like to sort on the first number and if those are equal on the last number. I tried this:

:%!sort -t';' -k2n -k3n

but this will affect the comments section. I know i can make vim ignore the comments like this:

:sort /^#/

but how do i select the fields now?? Does the shell sort have a field ignorer? Or can the VIM sort use fields?

BTW the comments section's length can increase so head/tail won't work.

Upvotes: 0

Views: 598

Answers (1)

benjifisher
benjifisher

Reputation: 5122

I do not think that

:sort /^#/

does what you want. It will sort the comments, putting them at the end of the buffer, and leave the other lines in the original order. A lot closer to what you want is

:sort /;/

This will leave all comments at the top of the buffer, in the original order, and sort on the part of the line after the first ;. Probably lexicographic sort is not what you want. Instead, you could use

:sort /;/ n

This will do numeric sort, but ignore the part of the line after the first number.

In order to avoid sorting comment lines that happen to contain ; characters, you could use a more complicated pattern:

:sort /^\(\s*#\)\@!.\{-};/ n

or (using a feature that I may never have tried before)

:sort /^\s*[^#]\&.\{-\};/ n

I am old-school, and use vim's default settings, but a lot of people prefer the \v (very magic) setting. That makes these a little simpler:

:sort /\v^(\s*#)@!.{-};/ n
:sort /\v^\s*[^#]&.{-};/ n

OTOH, the version you suggested using the external sort seems to work perfectly.

$ sort --version
sort (GNU coreutils) 5.93

Upvotes: 1

Related Questions