Linux 上的 GNU sed 與 macOS 內的 sed 的 in-place 差異

結論:用 Perl

寫 shell script 的時候遇到的問題,在 Linux 上面使用 sed 換檔案裡面的字串,但不想要產生 backup file 的方式是:

sed -i -e 's/foo/bar/' example.txt

但在 macOS 內建的 sed 則是:

sed -i '' -e 's/foo/bar/' example.txt

也就是說前者 GNU sed 是處理 $1 (argv[1],anyway) 後面貼著的參數,而後者 macOS 的則是吃 $2 (argv[2]) 的參數。

Stack Overflow 上的「sed in-place flag that works both on Mac (BSD) and Linux」這邊有討論,看起來 sed 上沒有通解。

翻了 The Open Group 上的說明,sed 應該是定義在 POSIX 裡面,而從文件裡面沒有提到 backup file 可以知道這是各家自己實作的功能:「sed」。

所以一種解法是用 detection 的方式針對不同的 sed 給不同的指令;而另外一種解法是找其他工具。後者考慮到普及性,用 Perl 應該會是比較好的方式,目前不是 minimal 類的系統應該都還有 Perl 可以用:

perl -pi -e 's/foo/bar/' example.txt

但這樣跑在 CI 裡面的時候就得小心一點了,如果選到 minimal image 的話就會中獎... (煩躁?)