6

Currently, I have

grep -irl $schema $WORKDIR/ | xargs sed -i 's/'"$schema"'/EXI1/gI'

which doesn't work for filenames with spaces.

Any ideas, how to search and replace recursively for all files?

Thanks

rojanu
  • 1,592
  • 5
  • 20
  • 34

2 Answers2

17

Add the -Z (aka --null) flag to grep, and the -0 (also aka --null) flag to xargs. This will output NUL terminated file names, and tell xargs to read NUL terminated arguments.

eg.

grep -irlZ $schema $WORKDIR/ | xargs -0 sed -i 's/'"$schema"'/EXI1/gI'
Hasturkun
  • 35,395
  • 6
  • 71
  • 104
3

find with sed should work:

find $WORKDIR/ -type f -exec sed -i.bak "s/$schema/EXI1/gI" '{}' +

OR

find $WORKDIR/ -type f -print0 | xargs -0 sed -i.bak "s/$schema/EXI1/gI"
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    This solution is better because it doesn't search each file twice (once with grep, once with sed). This should be chosen over the other. –  Jun 25 '13 at 12:57
  • 1
    Above commands doesn't search the content of the file like grep all it does is find all the files in the WORKDIR. My command uses grep to find the files that contains the $schema and passes the files to sed to do the replace, this way only the files that contain the $schema are touched. whereas with find all files are touched – rojanu Jun 25 '13 at 13:36
  • 1
    You don't really need to search using grep since using sed you're anyway doing search & replacement. – anubhava Jun 25 '13 at 13:37