2

Here's the test script I'm running

matt@server:~ $ cat test.sh
#!/bin/bash
mkdir test
cd test
echo "has the string foo" > yes.txt
echo "hasn't the string" > no.txt
ls -l --time-style=full-iso
cat *
perl -e 's/foo/bar/g;' -pi $(find -type f)
ls -l --time-style=full-iso
cat *
matt@server:~ $ ./test.sh
total 8
-rw-r--r-- 1 matt matt 18 2011-01-29 13:52:17.240316663 -0700 no.txt
-rw-r--r-- 1 matt matt 19 2011-01-29 13:52:17.240316663 -0700 yes.txt
hasn't the string
has the string foo
total 8
-rw-r--r-- 1 matt matt 18 2011-01-29 13:52:17.260317727 -0700 no.txt
-rw-r--r-- 1 matt matt 19 2011-01-29 13:52:17.260317727 -0700 yes.txt
hasn't the string
has the string bar

I need to figure out how to tweak this line:

perl -e 's/foo/bar/g;' -pi $(find -type f)

To not write every file it finds but to just write the files that need to be changed.

2 Answers 2

2

This should be a suitable replacement:

grep -l foo * | sed -e 's/[^/0-9A-Z_a-z]/\\&/g' | xargs sed -i 's/foo/bar/g'

1
  • Note that special characters in file names (\'" and whitespace) need to be protected against expansion by xargs. Jan 30, 2011 at 19:10
2

Try this:

perl -e 's/foo/bar/g;' -pi `egrep -l 'foo' $(find -type f)`

That searches for the regular expression and returns on the filenames where it is found. Then Perl will operate only on those files.

2
  • Might as well run $(egrep -rl 'foo' .)
    – jsbillings
    Jan 29, 2011 at 23:37
  • Using the result of command substitution as a list of file names doesn't work if the file names can contain special characters (\[*? or whitespace). This is also a problem in the question. Jan 30, 2011 at 19:11

You must log in to answer this question.

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