Macに入っているsedはBSD版sedとかいうやつで、Linuxなどに入っているGNU版sedとは様々な点で仕様が異なります。
中でも引っかかりやすいのがファイル上書きオプションの-i
についてです。あんまりちゃんと説明した記事が見当たらないのでまとめておきます。
以下のようなコマンドを実行すると、BSD sedでは意図通りに実行されません。
$ echo aaabbbcc > hoge.txt
$ sed -i 's/aaa/zzz/' hoge.txt # BSD sed
sed: 1: "hoge.txt": extra characters at the end of h command
$ gsed -i 's/aaa/zzz/' hoge.txt # GNU sed
$ cat hoge.txt
zzzbbbcc
ここでman sed
の該当部分を読んでみます。
i extension
Edit files in-place, saving backups with the specified extension.
「saving backups with the specified extension.」とあります。つまり、**BSD sedでの上書き保存には、バックアップ用拡張子の指定が必須なのです。**先ほどのコマンドでは、's/aaa/zzz/'
がバックアップ用拡張子として認識されてしまいます。
つまり、正しいコマンドは以下のようになります。
$ sed -i '.bak' 's/aaa/zzz/' hoge.txt # 拡張子'.bak'でバックアップ
$ cat hoge.txt
zzzbbbcc
$ cat hoge.txt.bak
aaabbbcc
拡張子を**「なし」に指定する場合**、バックアップされません。
$ echo aaabbbcc > fuga.txt
$ sed -i '' 's/aaa/zzz/' fuga.txt # バックアップファイルは生成されない
$ cat fuga.txt
zzzbbbcc
まとめると、Macに最初から入っているsedで上書きのみをする場合、オプションは-i ''
と覚えておけばよいでしょう。