4

How to execute the same command with arguments that are delivered by another command via pipe?

As a result of the extraction of file names from a source I get:

    $some_command
    filename1
    filename2
    filename3
    ...
    filenameN

I'd like to create files with these filenames with touch. How can I loop touch over these names?

5 Answers 5

7

I only use for ... do ... done for very simple cases.

For more complicated/dangerous scenarios:

command | sed 's/^/touch /'

This does nothing but prints intended commands. Review the results, then perform the same thing piping to sh -x (the -x flag is for debugging):

command | sed 's/^/touch /' | sh -x
11

You can use xargs with -n1 to run a command once for each piped argument

$some_command | xargs -n 1 touch

In the case of touch however which accepts multiple arguments

touch `$some_command` 

will probably work for you.

1
  • theotherreceive is correct, you can also use $some_command | xargs -I {} touch -option {} .This is helpful when you need to use options on your xarg execution.
    – Geo
    Jul 1, 2009 at 20:20
4
for i in `$some_command`; do touch $i; done
3
  • ...and hope none of the filenames have whitespace.
    – hark
    Jul 1, 2009 at 18:48
  • 1
    Put double quotes around $i to take care of spaces.
    – Not Now
    Jul 1, 2009 at 20:44
  • Not quite mr. Bash. First of all, he has to set the IFS variable and later remember to restore it to old value.
    – kubanczyk
    Jan 5, 2010 at 14:10
2

If the filenames contain whitespace, then the following will work around them:

some_command | while read filename ; do touch "$filename" ; done

This will create files named:
file name 1
file name 2
named file 3
etc

Assuming, of course, that it does produce those names.

1
  • It will NOT work with whitespace... You need touch "$filename".
    – kubanczyk
    Jan 5, 2010 at 14:14
1

"some_command | xargs touch" will probably do the trick, however there are two pitfalls:

  1. If a filename contains any whitespace character it will be treated as a separator, for example a filename "fuh bar" will, this way, be "touch"ed as a file named "fuh" and another one named "bar" instead of a single "fuh bar" one. To alleviate this you may check if your "some_command" is able to produce another delimiter, often NULL (see the "-print0" argument legit with the command "find"), and use the "--null" argument of xargs
  2. If the command does not produce anything xargs will fail miserably. Use its "--no-run-if-empty" argument

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .