6

I'm trying to execute a sequence of commands on a list of files one by one. I was wondering if it is possible to use xargs something on the lines of

ls *.txt | xargs -n 1 -I {} cat {} | grep foo > {}.foo

Where

cat {} | grep foo > {}.foo

is the command I want to execute on each file.

7

It might be possible to use something along the lines of

xargs -n1 -I[] sh -c 'cat {} | grep foo > {}.foo'

or, to get rid of the useless cat

xargs -n1 -I{} sh -c 'grep foo {} > ().foo'

It's usually easier to put it in a shell script so you can just pass it files.

cat > fiddle.sh <<\EOF
for f in "$@"; do
  grep foo "$f" >"$f.foo"
done
EOF
ls *.txt | xargs sh fiddle.sh    # note we can now pass multiple files, no -n1 or -I needed

Pedantry: ls won't do the right thing with special characters, notably embedded newlines, in filenames. I'd dump the xargs entirely, and (given the above script) just do

sh fiddle.sh *.txt

or even

for f in *.txt; do grep foo "$f" >"$f.txt"; done

right at the prompt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.