Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33864

Strange vim regular expressions behaviour

I am not sure what exactly is going on here but I was trying to remove some data from a file using vim. The data is 6 comma separated vales. I want to remove the last three from every line. I used the regular expression find replace %s/,[0-9]*,[0-9]*,[0-9]*$//g. I use it on the following data:

7.95630550,-3.53701925,-1.04588318,52,40,40
2.60749245,-3.85793233,0.43392944,77,41,19
10.12495995,1.63384104,1.23306274,40,31,42
10.14402199,-3.11163330,1.23091125,40,29,36
-0.49531555,-3.59129953,-1.24293518,62,53,52

And i get this:

7.95630550,-3.53701925,-1.04588318
2.60749245,-3.85793233,0.43392944
10.12495995,1.63384104,1.23306274,40,31,42
10.14402199,-3.11163330,1.23091125,40,29,36
-0.49531555,-3.59129953,-1.24293518

So some of the data is removed but for some reason the data in those other lines is not removed. This is happening all over the file and I cant see any describable pattern? Is there something wrong with my expression?

Upvotes: 0

Views: 173

Answers (5)

Peter Rincker
Peter Rincker

Reputation: 45097

Alternatively use cut:

:%!cut -d, -f 1-3
  • Cut extracts text from a file for more help see man cut
  • -d, set comma as the delimiter
  • -f 1-3 you want to "cut" or extract fields 1-3
  • :%!{cmd} filter the entire file through shell command, {cmd}. See :h :range!

Upvotes: 1

romainl
romainl

Reputation: 196496

For what it's worth, your command works as intended on the given sample, here, so the problem is probably outside of your regular expression.

But why make it so damn complicated?

:%norm $3F,D

Upvotes: 3

Alexis Wilke
Alexis Wilke

Reputation: 20720

You're missing an asterisk on the last one and you don't need /g at the end:

:%s/,[0-9]*,[0-9]*,[0-9]*$//

That being said, to make it safer, you probably want to use the + instead of the *, and in that case you need to escape it:

:%s/,[0-9]\+,[0-9]\+,[0-9]\+$//

Upvotes: 0

Barton Chittenden
Barton Chittenden

Reputation: 4416

When dealing with delimited files, you can use the compliment of the delimiter, by specifying it in a character class -- e.g. if the delimiter is ,, the compliment is [^,]

%s/\(,[^,]\+\)\{3\}$//

This replaces 3 of the group of "comma, followed by one or more non-comma characters" followed by end of line. with nothing.

Upvotes: 1

Amit
Amit

Reputation: 20456

This regex should work if the number of fields is constant as it is searching from the beginning of the line.

:g/\(.\{-}\zs,\)\{3}/normal nd$

On each line go the 3 occurrence of , and delete to the end of line.

Upvotes: 1

Related Questions