On macOS Monterey, why this:
$ sed -i -e 's/<azure\/core\/internal\//</g' -e 's/<azure\/core\//</g' -e 's/<azure\/iot\/internal\//</g' -e 's/<azure\/iot\//</g' .
… ends up with the following error:
sed: -e: No such file or directory
On macOS Monterey, why this:
$ sed -i -e 's/<azure\/core\/internal\//</g' -e 's/<azure\/core\//</g' -e 's/<azure\/iot\/internal\//</g' -e 's/<azure\/iot\//</g' .
… ends up with the following error:
sed: -e: No such file or directory
Like mentioned in the comments, with the BSD version of sed, -i
takes a mandatory argument, so in sed -i -e
, the -e
becomes that argument, the filename suffix used for backup files. Then, the next argument in your command is s/<azure\/core\/internal\//</g
, and since the -e
or -f
options weren't seen, that's the sed script. (This is similar to how both grep pattern file...
and grep -e pattern file...
work and do the same.)
The standard behaviour is that options have to appear as the first command line arguments. So after the first non-option, the rest are not interpreted as options, even if they begin with dashes. So sed
takes them as filenames, starting with the -e
.
That's also different on GNU, where e.g. ls dir -l
does the same as ls -l dir
. But it's not standard, and the BSD sed on mac doesn't support it.
On GNU, sed foo -e bar
would recognize -e
as an option, take bar
as the sed script, and foo
as a filename. But with the standard interpretation, foo
would be the script, and -e
and -bar
filenames.
Fix the issue with -i
, and the rest falls into place. To use the -i
option without a backup file on mac, use
sed -i '' -e something -e something file...
Note that sed -i.bak
would work with either version of sed to set the backup suffix to .bak
. (but sed -i .bak
would not)
Ok, here is my solution:
sed -i '' -e 's/<azure\/core\/internal\//<azure-sdk-for-c\//g;s/<azure\/core\//<azure-sdk-for-c\//g;s/<azure\/iot\/internal\//<azure-sdk-for-c\//g;s/<azure\/iot\//<azure-sdk-for-c\//g' ./azure-sdk-for-c/*
-e
options though, and you can make the substitutions look nicer by using an alternate delimiter: sed -i '' -e 's,<azure/core/internal/,,g' -e 's,<azure/core/,,g' -e ...
.
– Kusalananda
Dec 19 '21 at 22:17
-e
is getting eaten as the backup suffix argument for the-i
option, causing subsequent-e
s to be treated as filename arguments – steeldriver Dec 19 '21 at 20:44