views:

2764

answers:

6

Say I have the following style of lines in a text file:

"12" "34" "some text     "
"56" "78" "some more text"
.
.
.
etc.

I want to be able to remove the quotes surrounding the first two columns. What is the best way to do this with VIM (I'm currently using gVim)?

I figured out how to at least delete the beginning quote of each line by using visual mode and then enter the command '<,'>s!^"!!

I'm wondering if there is a way to select an entire column of text (one character going straight down the file... or more than 1, but in this case I would only want one). If it is possible, then would you be able to apply the "x" command (delete the character) to the entire column.

There could be better ways to do it. I'm looking for any suggestions.


Update

Just and FYI, I combined a couple of the suggestions. My _vimrc file now has the following line in it:

let @q=':%s/"\([0-9]*\)"/\1/g^M'

(NOTE: THE ^M is CTRL-Q + [Enter Key] to emulate pressing the Enter key after running the command)

Now I can use a macro via @q to remove all of the quotes from both number columns in the file.

Thanks to everyone for their help.

+12  A: 

Control-V is used for block select. That would let you select things in the same character column.

It seems like you want to remove the quotes around the numbers. For that use,

:%s/"\([0-9]*\)"/\1/g

Here is a list of what patterns you can do with vim.


There is one more (sort of ugly) form that will restrict to 4 replacements per line.

:%s/^\( *\)"\([ 0-9]*\)"\([ 0-9]*\)"\([ 0-9]*\)"/\1\2\3\4/g


And, if you have sed handy, you can try these from the shell too.

head -4 filename.txt | sed 's/pattern/replacement/g'

that will try your command on the first 4 lines of the file.

nik
I was able to do block selecting and deleting in ED4W (different editor), so I figured Vim must let you do something similar. However, you're right in what I really want is to remove quotes from around the numbers. This is exactly what I was looking for. Thank you!
Jason Down
This actually removed the quotes around the other text as well (the third column). I'm sure I can play around with it to make it work though.
Jason Down
Did other columns also have plain numbers with quotes? else it wouldn't do that.
nik
No, none of them do. Very strange, because from what I can tell in the documentation, your example should work perfectly.
Jason Down
That is very odd, I am adding a variation for you to check.
nik
Works for my situation, since this file will always be generated with the exact same format. I had to change the command from :s to :%s to make it work, but other than that, worked like a charm.
Jason Down
I liked your first example the best. I made one modification and this seemed to work::%s/"\([0-9]*\)\"/\1/gor could use:%s/"\([0-9]*\)\"/\1/g
Jason Down
@Jason, Oh, my bad. That was a silly typo. Fixing that now.
nik
Guess what! i had another typo right in the first example. Figures why you couldn't use it :-( i must be sleepy or something. Fixing immediately.
nik
Its funny how once you have solved something, it really takes another person to find such bugs. Your mind has sort of blocked-out the 'fixed' part! You clearly pointed out that it did not work, and yet i never got around looking at that missing ". So did your other columns start with numbers? that would explain my bug manifesting.
nik
You don't need to escape the quote. The first answer i gave (alas with a typo) was the actual answer. Others should be used just to learn a bit more about these pattern techniques.
nik
Actually, escaping the quote was a typo on my part lol. Regular expressions are not nice on the eyes...
Jason Down
+2  A: 

See column editing in vim. It describes column insert, but basically it should work in the same way for removing.

wazoox
+1  A: 

You could also create a macro (q) that deletes the quotes and then drops down to the next line. Then you can run it a bunch of times by telling vi how many times to execute it. So if you store the macro to say the letter m, then you can run 100@m and it will delete the quotes for 100 lines. For some more information on macros:

http://vim.wikia.com/wiki/Macros

Bryan Ward
+5  A: 

use visual block commands:

  • start mode with Ctrl-v
  • specify a motion, e.g. G (to the end of the file), or use up / down keys
  • for the selected block specify an action, e.g. 'd' for delete

For more see :h visual-mode

fgm
Note that if using Vim under Windows, this won't work (perhaps with the right config it may).
Robert Gowland
Well, no, because Vim on Windows usually has mswin.vim loaded, which remaps Ctrl-V to paste. Instead, Ctrl-Q should enter Visual mode, as per :h mswin.
Michael Madsen
+1  A: 

The other solutions are good. You can also try...

:1,$s/^"\(\w\+\)"/\1/gc

Also see... http://www.geocities.com/volontir/ for more VIM regex help.

kervin
Tried it out (I removed the c to get rid of the confirm mode, but kept it the same other than that). It seemed to only remove the quotes around the first column.
Jason Down
Right, to do just the first two you'd use::%s/^"\(\d\+\)"\s\+"\(\d\+\)"/\1 \2/If the space between the numbers is important, you can capture that too::%s/^"\(\d\+\)"\(\s\+\)"\(\d\+\)"/\1\2\3/
TMN
Ah, makes sense.
Jason Down
+3  A: 

Although this case was pretty simple to fix with a regex, if you want to do something even a bit more advanced I also recommend recording a macro like Bryan Ward. Also macros come easier to me than remembering which characters need to be escaped in vim's regexes. And macros are nice because you can see your changes take place immediately and work on your line transformation in smaller bits at a time.

So in your case you would have pressed qw to start recording a macro in register w (you can of course use any letter you want). I usually start my macros with a ^ to move to the start of the line so the macro doesn't rely on the location of the cursor. Then you could do a f" to jump to the first ", x to delete it, f" to jump to the next " and x to delete that too. Then q to finish recording.

Instead of making your macro end on the next line I actually as late as today figured out you can just V (visually line select) all lines you want to apply your macro to and execute :normal @w which applies your macro in register w to each visually selected line.

Sam
I haven't done much with Macros, but I can see them being very useful. This is something I have to do often enough that I need a convenient way to do it, but I don't do it enough that remembering the regex would be easy. A macro is probably the better solution in this case (though I really should work on master regex... as they come in handy for programming in .NET as well).
Jason Down