Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed command creating unwanted duplicates of file with -e extension

Tags:

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?

enter image description here

like image 737
nserror Avatar asked Dec 30 '15 17:12

nserror


People also ask

Does sed overwrite file?

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).

What is $P in sed?

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.


2 Answers

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 
like image 101
anubhava Avatar answered Oct 10 '22 18:10

anubhava


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.

  1. Don't use -i (inplace). Instead pipe to a temporary file and overwrite the original after.
  2. use perl.

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

like image 35
Eric Blum Avatar answered Oct 10 '22 18:10

Eric Blum