Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
up vote 6 down vote accepted

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.

share|improve this answer
    
Worked nicely. Thanks. – anand.trex Mar 23 '11 at 22:10

You must log in to answer this question.

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