macos - In-place edits with sed on OS X

ID : 20403

viewed : 26

Tags : macosfile-iosedin-placemacos

Top 5 Answer for macos - In-place edits with sed on OS X

vote vote

93

You can use the -i flag correctly by providing it with a suffix to add to the backed-up file. Extending your example:

sed -i.bu 's/oldword/newword/' file1.txt 

Will give you two files: one with the name file1.txt that contains the substitution, and one with the name file1.txt.bu that has the original content.

Mildly dangerous

If you want to destructively overwrite the original file, use something like:

sed -i '' 's/oldword/newword/' file1.txt       ^ note the space 

Because of the way the line gets parsed, a space is required between the option flag and its argument because the argument is zero-length.

Other than possibly trashing your original, I’m not aware of any further dangers of tricking sed this way. It should be noted, however, that if this invocation of sed is part of a script, The Unix Way™ would (IMHO) be to use sed non-destructively, test that it exited cleanly, and only then remove the extraneous file.

vote vote

86

I've similar problem with MacOS

sed -i '' 's/oldword/newword/' file1.txt 

doesn't works, but

sed -i"any_symbol" 's/oldword/newword/' file1.txt 

works well.

vote vote

78

The -i flag probably doesn't work for you, because you followed an example for GNU sed while macOS uses BSD sed and they have a slightly different syntax.

All the other answers tell you how to correct the syntax to work with BSD sed. The alternative is to install GNU sed on your macOS with:

brew install gsed 

and then use it instead of the sed version shipped with macOS (note the g prefix), e.g:

gsed -i 's/oldword/newword/' file1.txt 

If you want GNU sed commands to be always portable to your macOS, you could prepend "gnubin" directory to your path, by adding something like this to your .bashrc/.zshrc file (run brew info gsed to see what exactly you need to do):

export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" 

and from then on the GNU sed becomes your default sed and you can simply run:

sed -i 's/oldword/newword/' file1.txt 
vote vote

69

sed -i -- "s/https/http/g" file.txt 
vote vote

53

You can use -i'' (--in-place) for sed as already suggested. See: The -i in-place argument, however note that -i option is non-standard FreeBSD extensions and may not be available on other operating systems. Secondly sed is a Stream EDitor, not a file editor.


Alternative way is to use built-in substitution in Vim Ex mode, like:

$ ex +%s/foo/bar/g -scwq file.txt 

and for multiple-files:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.* 

To edit all files recursively you can use **/*.* if shell supports that (enable by shopt -s globstar).


Another way is to use gawk and its new "inplace" extension such as:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 

Top 3 video Explaining macos - In-place edits with sed on OS X

Related QUESTION?