I've successfully used the following sed
command to search/replace text in Linux:
sed -i 's/old_link/new_link/g' *
However, when I try it on my Mac OS X, I get:
"command c expects \ followed by text"
I thought my Mac runs a normal BASH shell. What's up?
EDIT:
According to @High Performance, this is due to Mac sed
being of a different (BSD) flavor, so my question would therefore be how do I replicate this command in BSD sed
?
EDIT:
Here is an actual example that causes this:
sed -i 's/hello/gbye/g' *
The -i
option (alternatively, --in-place
) means that you want files edited in-place, rather than streaming the change to a new place.
Modifying a file in-place suggests a need for a backup file - and so a user-specified extension is expected after -i
, but the parsing of the extension argument is handled differently under GNU sed & Mac (BSD) sed:
-i
, with no intervening space.So GNU & Mac will interpret this differently:
sed -i 's/hello/bye/g' jkl.txt
-i
, so create no backup, use s/hello/bye/g
as the text-editing command, and act on the file jkl.txt
in-place.s/hello/bye/g
is the backup file extension (!), use jkl.txt
as the text-editing command, but uh-oh!: the command code given there is j
(not, eg s
, a valid command code for substitution), so error with invalid command code j
.To get a portable command, you can use this invocation, that works across both GNU sed
and Mac (BSD) sed
in Mac OS X Mavericks (v10.9, released June 2013) and above:
sed -i'' -e 's/hello/bye/g' jkl.txt
Placing the extension immediately after the -i
(eg -i''
or -i'.bak'
, without a space) is what GNU sed
expects, and is now accepted by Mac (BSD) sed
too, though it wasn't tolerated by earlier versions (eg with Mac OS X v10.6, a space was required after -i
, eg -i '.bak'
).
The -e
parameter allows us to be explicit about where we're declaring the edit command.
Until Mac OS was updated in 2013, there wasn't any portable command across GNU and Mac (BSD), as these variants also failed:
sed -i -e ...
- does not work on OS X as it creates -e
backupssed -i '' -e ...
- fails on GNUWhen there wasn't a sed
command working on all platforms, you could have tried using another command to achieve the same result, e.g. perl -i -pe's/old_link/new_link/g' *
.