2

Give a buffer each line contain a filename. how to use r! cmd on the filename, within a :g command?

eg,

BEFORE PROCESSING:

file1.txt  
file2.txt

AFTER PROCESSING (with wc -l):

file1.txt  
12 file1.txt  
file2.txt  
23 file2.txt

P.S.
extra kudos for using a submatch instead of whole line in the solution.

1 Answer 1

2

With a file on every line and assuming each file either has a path or can be found in the current directory:

:g/./ r !wc -l <cfile>

Per :h :<cfile>, <cfile> is a special token that when encountered on the command line

is replaced with the path name under the cursor.

This might not be quite what you expected as your "P.S." suggests you want to use backreferences or equivalent to find files that make up only part of each line. Well, I don't know about that but here's an approximation of that functionality...

Let's say that our lines are made up of a word followed by whitespace followed by a filename:

foo file1.txt
bar file2.txt

The command above will not work because :global just puts the cursor at the beginning of each line before processing it. So to use <cfile> we need some way to demarcate the file name and get the cursor on it.

:g/^\w\+\s\+\zs\S\+$/ exe "norm! n" | r !wc -l <cfile>

By using \zs in the pattern where the filename begins and then Normal mode command n (go to next match) the cursor is then in a position where we can make use of <cfile>. (The pattern could be a bit simpler but I'm being explicit/verbose for the sake of clarity.)

Note: we use exe "norm .. " instead of plain norm because otherwise we couldn't follow it with a non-Normal mode command.

1
  • Many thx. Fantastic use of <cfile>. Excellent!!
    – qeatzy
    May 11, 2018 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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