I am trying to do a recursive find and replace on java files in a directory using a shell script. It works, but it is hiding all the files, and creating duplicates with a -e extension
#!/bin/bash for file in $(find . -type f -name "*.java") do sed -i -e 's/foo/bar/g' $file done
From my understanding, the -e is optional - but if I do not provide it I get the following error on every file it finds
sed: 1: "./DirectoryAdapter.java": invalid command code .
Any clue as it what is happening here? For reference I am on Mac OS X running El Capitan
Here is a before and after screenshot of the directory after running the script. The replaced files still exist, they are hidden?
By default sed does not overwrite the original file; it writes to stdout (hence the result can be redirected using the shell operator > as you showed).
The p command prints out the pattern space to STDOUT. The p command is mostly only used in conjunction with the -n option to sed, because, otherwise, printing each line is sed's default behaviour. Using p and -n is another way to emulate the head command. Print only lines 1 to 3: sed -n 1,3p.
On OSX sed (BSD) sed
requires an extension after -i
option. Since it is finding -e
afterwards it is adding -e
to each input filename. btw you don't even need -e
option here.
You can pass an empty extension like this:
sed -i '' 's/foo/bar/g' $file
Or use .bak
for an extension to save original file:
sed -i.bak 's/foo/bar/g' $file
The accepted answer works for OSX but causes issues if your code is run on both GNU and OSX systems since they expect -i[SUFFIX]
and -i [SUFFIX]
respectively.
There are probably two reasonable solutions in this case.
The easiest fix for this I found was to simply use perl. The syntax is almost identical:
sed -i -e 's/foo/bar/g' $file
->
perl -pi -e 's/foo/bar/g' $file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With