tags:

views:

153

answers:

3

I want to sort on a certain column only for rows containing a certain word. I don't want to see rows not containing that word. For example I have this text file:

 sdf ggfds   7
 sdf sgs     5
 sdf dfgs    3
 foo dffg    2
 bar dffg    2
 sdf sddfg   4

I want to sort 3rd column for rows containing only "sdf" word (doesnt have to be in a first column)

and I want to see this output:

 sdf dfgs    3
 sdf sddfg   4
 sdf sgs     5
 sdf ggfds   7
+4  A: 

Pipe your input to an external command:

:%!grep sdf | sort -n -k3

Details:

  1. select the whole content using '%'
  2. pipe it to an external command using '!'
  3. grep onyl the lines containing 'sdf'
  4. sort these lines numerically (-n) on the third field (-k3)
Of course, this is only any good if you're on a computer with grep and sort installed - many Vim users on Windows will find this won't work and may not want to install gnuwin32 or cygwin.
Al
So far, this is the best and the most intuitive answer!
vehomzzz
+2  A: 

2 vim commands:

:v/sdf/d
:sort n /[^[:digit:]]*/
  • first deletes all lines that do not contain 'sdf'
  • second sorts numbers ignoring non-numbers
Maxim Kim
+1: A good native-Vim way to do it without having to spawn an external shell.
Al
an intersting way,Maxim, but I also want to sort on a specific column
vehomzzz
yep, it comes that os's sort make it easier to sort by a specific column but you can use :sort n /\v(\S+\s+){2}/ to do the same within vim as Al pointed out.
Maxim Kim
+1  A: 

Maxim Kim has already given an excellent answer and I was going to add this in a comment, but it just got too complicated so I'll stick it in an answer:

You could simplify the pattern by using:

:v/sdf/d
sort n /\D*/

as \D is equivalent to [^[:digit:]] and is a lot less typing. For more information, see

:help \D

To match on the third field specifically, rather than just the first digit, use

:sort n /\(\S\+\s+\)\{2}/`

or

:sort n /\v(\S+\s+){2}/

See:

:help :sort
:help \S
:help \s
:help pattern.txt
:help \v

As an aside, some find it easier to remember :g!/sdf/d, which does the same as :v/sdf/d - :g! is the opposite of :g and is identical to :v.

:help :v
:help :g
Al