tkuchikiの日記

新ブログ https://blog.tkuchiki.net

BSD(Mac) で find xargs sed を使う際の注意点

ファイルを一括置換するときに、

find /path/to/dir -type f | xargs sed -i "s/hoge/foobar/g"


みたいにコマンドを打つことがあると思いますが、
Macでは、

sed: 1: "/path/to/dir": invalid command code .

や、

sed: 1: "path/to/dir/file": extra characters at the end of p command


のようなエラーが出る。
これは、MacsedBSD のものらしく、GNUBSD と使い方が若干違うようです。
そのため、GNUsed をインストールして使うことで対応できるようです。
参考(grepした結果をsed(正規表現置換)したかったときにMacだとハマった話 - 憧れ駆動開発)

homebrew を使っているのであれば、以下のようにインストールできる。

brew install gnu-sed


sed を gsed に 変えればそのまま使える。

find /path/to/dir -type f | xargs gsed -i "s/hoge/foobar/g"


ただ、これだと BSD 環境では使えないので、BSD sed の書き方を調べてみる。

"-i" を使ってエラーがでた原因は、man を見たら書いてあった。

     -i extension
             Edit files in-place, saving backups with the specified extension.  If a zero-length
             extension is given, no backup will be saved.  It is not recommended to give a zero-
             length extension when in-place editing files, as you risk corruption or partial con-
             tent in situations where disk space is exhausted, etc.


"-i" のあとは、バックアップファイルの拡張子を指定しなくてはいけない模様。
FreeBSDのフォーラムでも質問されていた(The FreeBSD Forums • View topic - sed not working with -i?)。

従って、"-i" のあとに "" をつけてバックアップファイルを残さないようにすることで対応できる。

find . -type f | xargs sed -i "" "s/hoge/foobar/g"