xargs with multiple commands

Answer #1 93.7 %

To start with, there is virtually no difference between:

find . | grep "file_for_print" | xargs echo


find . -name "file_for_print*"

except that the second one will not match filenames like this_is_not_the_file_for_print, and it will print the filenames one per line. It will also be a lot faster, because it doesn't need to generate and print the entire recursive directory structure just in order for grep to toss most of it away.

find . -name "file_for_print*"

is actually exactly the same as

find . -name "file_for_print*" -print

where the -print action prints each matched filename followed by a newline. If you don't provide find with any actions, it assumes you wanted -print. But it has more tricks up its sleeve than that. For example:

find . -name "file_for_print*" -exec cat {} \;

The -exec action causes find to execute the following command, up to the \;, replacing {} with each matching file name.

find does not limit itself to a single action. You can tell it to do however many you want. So:

find . -name "file_for_print*" -print -exec cat {} \;

will probably do pretty well what you want.

For lots more information on this very useful utility, type:

man find


info find

and read all about It.

Answer #2 100 %

find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;' (OP was missing %s)

Answer #3 100 %

Since it's not been said yet: -I % tells xargs to replace '%' with the arguments in the command you give it. The sh -c '...' just means run the commands '...' in a new shell.


xargs -I % sh -c 'echo %; cat %;'

will run echo [filename] followed by cat [filename] for every filename given to xargs. The echo and cat commands will be executed inside a different shell process but this usually doesn't matter. Your version didn't work because it was missing the % signs inside the command passed to xargs.

For what it's worth I would use this command to achieve the same thing:

find -name "*file_for_print*" | parallel 'echo {}; cat {};'

because it's simpler (parallel automatically uses {} as the substitution character and can take multiple commands by default).

Tags: bashxargs

You’ll also like:

© 2023 CodeForDev.com -