Suppose I have some output from a command (such as ls -1
):
a
b
c
d
e
...
I want to apply a command (say echo
) to each one, in turn. E.g.
echo a
echo b
echo c
echo d
echo e
...
What's the easiest way to do that in bash?
This question is related to
bash
Better result for me:
ls -1 | xargs -L1 -d "\n" CMD
i like to use gawk for running multiple commands on a list, for instance
ls -l | gawk '{system("/path/to/cmd.sh "$1)}'
however the escaping of the escapable characters can get a little hairy.
You can use a basic prepend operation on each line:
ls -1 | while read line ; do echo $line ; done
Or you can pipe the output to sed for more complex operations:
ls -1 | sed 's/^\(.*\)$/echo \1/'
You actually can use sed to do it, provided it is GNU sed.
... | sed 's/match/command \0/e'
How it works:
xargs fails with with backslashes, quotes. It needs to be something like
ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
xargs -0 option:
-0, --null Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode.
ls -1
terminates the items with newline characters, so tr
translates them into null characters.
This approach is about 50 times slower than iterating manually with for ...
(see Michael Aaron Safyans answer) (3.55s vs. 0.066s). But for other input commands like locate, find, reading from a file (tr \\n \\0 <file
) or similar, you have to work with xargs
like this.
for s in `cmd`; do echo $s; done
If cmd has a large output:
cmd | xargs -L1 echo
Source: Stackoverflow.com