findとPerlワンライナーで複数ファイルの文字列を一括置換
あるディレクトリ以下のファイルの文字列を一括置換する方法。
find,xargs,perlで一括置換
カレントディレクトリ以下のテキストファイル(*.txt)の文字列"hoge"を"foo"に置き換えする場合。
$ find . -type f -name '*.txt' | xargs perl -i -pe 's/hoge/foo/g'
置換前のファイルをバックアップとして残しておきたい場合、perlの-iの後ろにバックアップファイルの拡張子を付けます。
(サンプルでは.bakとしてバックアップファイルを作成)
$ find . -type f -name '*.txt' | xargs perl -i.bak -pe 's/hoge/foo/g' $ $ ls -l total 32 -rw-r--r-- 1 foo bar 1100 8 21 00:57 test.txt -rw-r--r-- 1 foo bar 1100 8 21 00:48 test.txt.bak -rw-r--r-- 1 foo bar 1100 8 21 00:57 test2.txt -rw-r--r-- 1 foo bar 1100 8 21 00:48 test2.txt.bak
find -exec, perlで一括置換
xargsを使用しない場合、普通にfind -exec でも出来ます。
カレントディレクトリ以下のテキストファイル(*.txt)の文字列"hoge"を"foo"に置き換えする場合。
$ find . -type f -name '*.txt' -exec perl -i.bak -pe 's/foo/hoge/g' {} \;
ついでに「{} \;」の意味を復習。
「;」をエスケープしてあるところがキモかな?
UNIXの部屋 コマンド検索: find より
http://x68000.q-e-d.net/~68user/unix/pickup?keyword=find&target=command
% find . -name \*~ -exec rm {} \;
⇒ カレントディレクトリ以下の *~ をリストアップして「rm 検索したファイル名」を実行する。{}の場所には検索したファイル名が入る。; はコマンドの終了を表すが、シェルに「;」を解釈させず、find へ「;」を渡すためにエスケープしてある。また、「{}」と「\」の間には必ずスペースを空けなくてはならない。
perl以外にもsedでも同じような方法で一括置換ができます。
この辺りの一括置換とかを覚えておくと何かと役にたちます。