kobapan@wiLiki
Login
Linux

Linux:複数ファイル内の文字列を一括置換

'hoge'が含まれているファイルを検索

$ grep -l 'hoge' *

-l, --files-with-matches PATTERN に一致する FILE の名前のみ表示する

複数ファイルの文字列を一括置換

ファイル内の'hoge'を'hage'に置換する例。

$find ./ -type f | xargs sed -i 's/hoge/hage/g'
or
$ sed -i 's/hoge/hage/g' *

オプション

改行を含む複数行にマッチさせる場合

sedで複数行を扱うにはループという非常にややこしい書式になるので、Perlを使う

$ find . -name '*.md' | xargs perl -0pi -e 's/検索文字\n検索文字/置換文字\n置換文字\n置換文字/m'

-pでprint

コマンドライン中の文字列をスクリプトとして解釈させるには、-eを使う。

-iを指定すると、ファイルの出力は入力元となったファイル自身になる。

404 Blog Not Found:perl - ワンライナーの書き方入門

-pはデフォルトでは1行ずつ-eの引数を評価する。つまりセパレータが\n。

-0でセパレータがヌル文字(\0)になる。つまり、ファイル全体を一度に読み込むことになる(よって、巨大なファイルに実行するのはおすすめしない)。

また、正規表現のオプション修飾子にmを指定し複数行モードにする(s/hoge/fuga/m←このm)

perlのワンライナーで複数行の置換を行う - Qiita

区切り文字はなんでもいい

$find ./ -type f | xargs sed -i 's%hoge%hage%g'

カレントディレクトリを起点にするときは、以下同じ意味

$ find ./
$ find .
$ find

sed のスクリプトで使う メタ文字

\?とか忘れて、[0-9]? とやってしまうと、「数字と?という文字」にマッチになってしまうので、あれれ?となる。

スクリプトとは、sedのオプションで -e を指定したときの条件式。これがデフォルト。

正規表現を使うこともできて、オプションで -r を指定する。その場合は、メタ文字じゃなくて、普通の正規表現が使える。

つまり、[0-9]? は数字一文字があってもなくてもよい、になる。

以下全部一緒の動作

sed 's%hoge[0-9]\?%hage%g' input.txt
sed -e 's%hoge[0-9]\?%hage%g' input.txt
sed -r 's%hoge[0-9]?%hage%g' input.txt

Debian
Emacs
Firefox
Gauche
JavaScript
Linux
Scheme
org-mode/latex

More ...