在 Linux 的 sed 版本是 GNU,在 macOS 的 sed 版本是 BSD,兩者在使用上略有不同,踩到這個雷,紀錄一下

-i 參數的差異

最常見的就是 -i,如果沒有提供後綴,則原始文件將被覆蓋而不進行備份(in place)

下面的指令在 macOS 中是可以執行的

cat << EOF > test.txt
foo
bar
baz
EOF
sed -e 's/foo/bar/g' -i '' test.txt

但是在 Linux 中卻會噴錯 sed: can't read : No such file or directory

在 Linux 中只需要使用 -i 即可

sed -e 's/foo/bar/g' -i test.txt

更改 separator

另外一個技巧就是更換 separator s/regular expression/replacement/flags

如果使用 / 當作 separator,在正規表示式中有用到 / 的地方,需要使用 \ 跳脫,這會造成很難閱讀

echo '/home/example' | sed 's/\/home\/example/\/usr\/local\/example/'

可以使用其他的 separator 來代替(|, #, @

echo '/home/example' | sed 's|/home/example|/usr/local/example|'
echo '/home/example' | sed 's#/home/example#/usr/local/example#'
echo '/home/example' | sed 's@/home/example@/usr/local/example@'