複数ファイルの文字列置換をワンライナーで
サブフォルダを含めて複数のテキストファイル内を文字列置換したい。一括で。
フォルダ構成の想定は下記のような感じ。実際には、もっと深い階層にたくさんファイルがある。

findでファイルを抽出してsedにわたす。
以前、bashでの置換例を書きsedは遅いと書いた。
bashで文字列置換をする
遅くても便利なら使うのだ。
さて、”abc” を “efg” に書き換えるワンライナー(1行実行)の例は下記。
find . -type f -name "*.twig" -exec sed -i 's/abc/efg/g' {} +
これは、Gnu版のsedを使用する例
sed –version
sed (GNU sed) 4.2.2
同じコマンドをMacOSのBSD版で実施すると、エラーになる
エラーメッセージ「sed: 1: “./t2/index.twig”: invalid command code .」
これには、ちょっとはまって混乱した。
BSD版sedでは、バックアップをとらないとき -i ” という明示をしないとだめということらしい。
Macでは、下記のコマンドになる。
find . -type f -name "*.twig" -exec sed -i '' 's/abc/efg/g' {} +
逆に、GNUのsedでこれをやると、
エラー「sed: s/abc/efg/g を読み込めません: そのようなファイルやディレクトリはありません」
-i に関して互換性がない。
ちなみに、今回一括置換をやろうと思ったのは、EC-CUBEのバージョンアップで .twig ファイルの書式が変わり、修正が必要になったため。
{% for f in form if f.vars.eccube_form_options.auto_render %}
↓
{% for f in form|filter(f => f.vars.eccube_form_options.auto_render) %}
下記のようなワンライナーで処理。
find . -type f -name "*.twig" -exec sed -i 's/ if f.vars.eccube_form_options.auto_render %}/|filter(f => f.vars.eccube_form_options.auto_render) %}/g' {} +