15

When xargs redirects the first commands output into the second command's argument and there is no choice about which argument for which element of the output, then there is only one way, for instance:

ls | xargs file  # there are as many arguments as files in the listing,
                 # but the user does not have too choose himself

now if there is a need for choice:

ls | xargs file | grep image | xargs mv.....   # here the user has to 
                                               # deal  with two arguments of mv, first for source second for destination, suppose your destination argument is set already by yourself and you have to put the output into the source argument. 

How do you tell xargs to redirect the standard output of the first command into the argument of your choice of the second command ?

enter image description here

1 Answers1

41

You can use -I to define a place-holder which will be replaced with each value of the arguments fed to xargs. For example,

ls -1 | xargs -I '{}' echo '{}'

will call echo once per line from ls's output. You'll often see '{}' used, presumably because it's the same as find's place-holder.

In your case, you also need to pre-process file's output to extract the matching file names; since there's a grep in there we can just use awk to do both, and simplify the file invocation as well:

file * | awk -F: '/image/ { print $1 }' | xargs -I '{}' mv '{}' destination

If you've got GNU mv you could just use -t to pass multiple source files:

file * | awk -F: '/image/ { print $1 }' | xargs mv -t destination
Stephen Kitt
  • 434,908