1

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

2 Answers2

4

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)

ilkkachu
  • 138,973
0

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/*
  • You could still use multiple -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