grepした結果をsed(正規表現置換)したかったときにMacだとハマった話
だいたい基本的にLinux前提で書かれている
ググってよくみつかるのは以下のワンライナー
grep -r hoge * | xargs sed -i "s/hoge/hufa/g"
ハマってる話をあまり聞かない限りは、たぶんこれで基本的にできるんだろう。
Macだとsedがハマる
そもそもMacのsedはBSD経由のsedらしくて、GNU版のsedとは違うらしい。だから -i オプションがつかえなかった。ということでbrewでgnu-sedいれた。port版もちゃんとあるらしい
brew install gnu-sed
あるプロジェクト以下の文字列を一括変換したかった
grep -rl hoge ./ | xargs gsed -e -i "s/hoge/hufa/g"
できたし!!!!
@xxxxxxx ++
@yyyyyyy ++
@zzzzzzz ++
@hhhhhhhh ++
補足とか
あんまりちゃんと理解してないけど各種オプションについて。
grepはファイルから文字列を正規表現で取り出すコマンド。いつものアレですね。 -r で再帰的に読むのでディレクトリ以下を操作できる。-l はマッチしたファイルのみ表示
xargs はパイプでリダイレクトしたときに標準出力をひとつにまとめるやつ、でいいのかな?ひとつひとつ読み込むより一気にまとめて読み込むのでパフォーマンスがいい、らしい。
gsedはGNU版のsed。 -i で文字列の置換。 -e で変換内容の表示。標準出力に出力してくれる。あとは正規表現で置換。
まあ、素直にLinuxでGNU版をつかうか、Macは上記の魔法を使うって覚えちゃうし!!!!情弱乙!!!!
もういっこ補足
grep -rl hoge ./
これだと全部のファイルが対象になるのはいいけど、gitやmercurialを使っている場合はそっちの履歴までさかのぼってしまうかもしれない。なので、厳密には
find . -name "*.py" | grep hoge * | xargs gsed -e -i "s/hoge/huga/g"
こんな感じでfindで拡張子を指定したほうがいいかもしれない。未検証だけど。