1

How can I write out the nth word of all lines to a new file? For example, I want the second word of all lines wrote out in new_file.txt:

old_file.txt:

pippo pluto paperino 
gigi lui marco 
piero andrea chiara

new_file.txt:

pluto  
lui   
andrea
  • 1
    is shelling out to awk acceptable? Does it have to be from within vi/vim? – Jeff Schaller Jul 11 at 14:58
  • How are fields seperated? Is it a space or a tab? – Valentin Bajrami Jul 11 at 15:19
  • If these are names, could someone have a nickname, such as Jeff "data checker" Schaller, where the 2nd field contains a quoted delimiter? – Jeff Schaller Jul 11 at 15:20
  • 1
    I 'd like do this without awk. Words are separated by space. The word could be any thinks, not only name (as the ex.) – Andrea Spiezia Jul 12 at 8:17
  • You might want to check out the Vi and Vim Stack Exchange for questions on Vim! – filbranden Jul 18 at 12:29
2

First step, delete all but the second word on each line. This is a fairly straightforward :%norm command:

:%norm dwwhD

Which is like manually typing out dwwhD on each line, but faster. Second step, save to a new file:

:w new_file.txt

And then quit without saving so that old_file.txt stays unmodified:

:q!
  • Thanks a lot, but in my file a word is composed with '/' : "pippo/dui", the command dwwhD recognize pippo as single word (i.e. '/' is a word separator). Can I change word separator? – Andrea Spiezia Jul 12 at 8:20
  • solved: added the backslash ascii to the variable iskeyword in file .vimrc. Thank you! – Andrea Spiezia Jul 12 at 8:59
0

You can do this from the terminal command line using a simple bash script. First loop through the contents of the file. Then for each line, pipe an echo into awk and have awk extract the second column. Lastly redirect that text into a new file.

Putting all of that together:

while read line; do
    echo $line | awk '{print $2}' >> new_file.txt
done <old_file.txt
  • 3
    awk '{print $2}' old_file.txt > new_file.txt will work just as well, with no loop. – Stephen Kitt Jul 11 at 16:36
0

Use a :s command with a regular expression:

:%s/\v^\s*\S+(\s+(\S+).*)?/\2

The \v tells Vim to use the "very magic" style of regexps, which is similar to extended regexps in grep, or pcre.

The regexp matches a single word at the start, possibly preceded by some optional whitespace. Then, after some more whitespace, the second word is captured inside group \2. Finally, a .* matches the whole rest of the line.

The part after the first word is optional (grouped in parentheses and made optional with the final ?). This ensures lines with a single word will still be matched, and in this case they'll be replaced with a blank line, which I imagine is what should be expected of a line with a single word, since the second work is blank in that case. This is one advantage of using regexps for this task, as you get more control over what to do with lines that have corner cases.

Finally, group \2 is used for replacement. It captured the second word on the line, by itself.

You can then save the modified contents to the new filename:

:saveas new_file.txt

This will preserve your unmodified old_file.txt and will make sure further modifications of the current buffer will only go to new_file.txt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.