1

I am trying to do a recursive find and replace in HP-UX and am missing something.

What I have at the moment:

find . -name "*.java" | xargs sed 's/foo/bar/g'

know the problem is that it's not replacing the file inline. I believe on other OS's there is a -i flag, but it seems in my HP-UX version, there isn't.

Any suggestions?

Vijay
  • 65,327
  • 90
  • 227
  • 319
RobM
  • 303
  • 1
  • 4
  • 14

2 Answers2

2
find . -name "*.java" | xargs sed -i 's/foo/bar/g'

or

find . -name "*.java" | xargs perl -pi -e's/foo/bar/g'
Vijay
  • 65,327
  • 90
  • 227
  • 319
  • As mentioned, the -i flag doesn't work with my version of sed. The second option worked however. Thanks. – RobM Jan 11 '13 at 13:10
  • Even on my solaris -i is not available for sed .so i too use perl.but on a whole its the only way where sed does the replace in place. – Vijay Jan 11 '13 at 13:12
  • 1
    Note that the above will fail for file names that contain spaces (or some other characters). You'd need to use `find -print0` and `xargs -0` to get around that but -0 isn't available with xargs on Solaris and I don't think -print0 is available with find either. – Ed Morton Jan 11 '13 at 14:26
1

The simple, portable solution to run any tool you like on the files and change them "in-place" (sed -i uses a tmp file behind the scenes too) is just:

find . -name "*.java" |
while IFS= read -r file; do
   sed 's/foo/bar/g' "$file" > tmp && mv tmp "$file"
done

You can use that approach for sed, grep, cut, whatever you like:

find . -name "*.java" |
while IFS= read -r file; do
   grep "whatever" "$file" > tmp && mv tmp "$file"
done

The only thing that won't work on is files whose names contain newlines but nor would the find | xargs solution as-is and you should rename those if you have them anyway.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185