# How can I make external command use current line as input and append output to end of same line?

Using Vim 8.0

I'm trying to make a table where the first column is the name of a file and the second column the creation date of such file, to which I have access by the exif data.

I would like to achieve this in one line, just to learn how.

Currently, I'm using:

:!ls

To get all the filenames I'll be working with. (If I want to filter .pdf files from this, how can I grep them out?)

Then, I would like to run something like this:

:read !exif -t 0x9003 -m

(which writes the date in the next line) but having the output append to the same line where the filename is, leaving a space or comma to separate the columns.

Was thinking that maybe I should write the ouput of !exif -t 0x9003 -m to a register @a and then use :normal $a<C-R>a to append it, but, again, failed to figure out how to do that. Another idea was to use :execute ':normal A ' . "foo" ,this almost works, but cannot figure out a way to use the output of exif instead of "foo". Thank you very much. ## 2 Answers There are two ways to approach this. Go heavy on the Vim or do what a rational person would do in the real world: lean heavily on the shell and let it do all the work as that's its strength. Though this is Vi/Vim SE I'm going to be contrarian and show the practical solution. ;) Let's say you use Bash and you want to run exif on all PNG files in a certain directory. One way is: for f in ~/images/*.png; do printf "%s : %s\n" "$f" "$(exif -t XXX -m "$f")"
done


The key to this one is the "process substitution" feature $(exif -t XXX -m "$f"). You'll get each PNG file name followed by a : and then the exif command output for that file.

You can just cram that all on a Vim command line like this:

:r !for f in ~/images/*.png; do printf "\%s : \%s\n" "$f" "$(exif "$f")"; done  (Note that you have to escape % here as otherwise Vim interprets them as special characters.) Or you can put those shell commands in a script and just do: :r !myscript.sh  BTW, if you want to loop over all files in a dir except PDFs then you can use for f in ~/images/*.!(pdf) but you'll need to first enable that syntax with shopt -s extglob. Since the bulk of the action is happening on external commands here, using a shell script is probably most appropriate in this particular case. If you do want to execute this inside Vim, then using the system() function is a great way to execute an external command and get the result into a string. (You can then use trim() to remove the trailing newline. You can also use shellescape() to escape filenames to safely pass them as arguments to the external command.) To modify lines in place, I'd recommend using a :s command, in particular using \= in the replacement part to use the result of a Vimscript expression as the replacement. You can then use submatch(0) to access the original matched text. Finally, you can use :v to exclude the lines which have filenames with the .pdf extension. Putting it all together: :v/\.pdf$/s/.\+/\=submatch(0)."\t".trim(system("exif -t 0x9003 -m ".shellescape(submatch(0))))


This will append the EXIF info to the lines with the filenames, using a Tab character as a separator.

Assumes your input was acquired with :0read !ls or similar, the buffer has a list of filenames to handle. Empty lines will be skipped by the .\+ match, so they're ok too.