grep に一致するすべてのファイルで文字列を検索して置換しようとしています:
grep -n 'foo' *
次の形式で出力が得られます。
[filename]:[line number]:[text]
foo
grep によって返された各ファイルについて、. に置き換えてファイルを変更したいと思いますbar
。
あなたが与えた例に基づいて、これはあなたが望むもののようです:
sed -i 's/foo/bar/g' *
再帰的ではありません(サブディレクトリに降りることはありません)。ツリー全体で選択したファイルを置き換える優れたソリューションとして、findを使用します。
find . -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
これ*.html
は、ファイルが一致する必要のある式であり、元のファイルのコピーを作成した.bak
後、-i
拡張子は.bak(任意の拡張子にすることができます)g
で、sed式の最後にあるはsedに複数のコピーを置き換えるように指示します。 1行(最初の行だけではなく)。-print
検索は、どのファイルが一致していたかを示すのに便利です。これはすべて、システム上のこれらのツールの正確なバージョンによって異なります。
grep で一致したすべてのファイルの文字列を検索して置換するということですか?
perl -p -i -e 's/oldstring/newstring/g' `grep -ril searchpattern *`
編集
これはかなり人気のある質問のように思われるので、更新したいと思います。
最近はack-grep
使い勝手が良いのでよく使っています。したがって、上記のコマンドは次のようになります。
perl -p -i -e 's/old/new/g' `ack -l searchpattern`
ファイル名の空白を処理するには、次を実行できます。
ack --print0 -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'
でさらに多くのことができますack-grep
。検索を HTML ファイルのみに制限したいとします。
ack --print0 --html -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'
空白が問題にならない場合は、さらに短くなります。
perl -p -i -e 's/old/new/g' `ack -l --html searchpattern`
perl -p -i -e 's/old/new/g' `ack -f --html` # will match all html files
sed(1)
オプションがある場合は、次の-i
ように使用します。
for i in *; do
sed -i 's/foo/bar/' $i
done
そうでない場合は、使用する言語に応じて、次のいくつかの方法があります。
ruby -i.bak -pe 'sub(%r{foo}, 'bar')' *
perl -pi.bak -e 's/foo/bar/' *
私は上記のソリューションまたはシステム全体の検索と数千のファイルの置換を気に入って使用しました。
find -name '*.htm?' -print -exec sed -i.bak 's/foo/bar/g' {} \;
「*.htm?」.html の代わりに、.htm ファイルと .html ファイルを同様に検索して見つけます。
.bak をシステム全体で使用されるチルダ (~) に置き換えて、バックアップ ファイルのクリーンアップを容易にします。
これは、perl や find を使用する必要なく、grep を使用して機能します。
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>
複数のスペースを含むファイル名を一度に処理し、バッチごとに 1 つのインタープリターをロードします。はるかに高速。
findとsedの使用について既に与えられた答え
find -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
おそらく標準的な答えです。perl -pi -e s/foo/bar/g'
または、コマンドの代わりに使用できますsed
。
ほとんどの場合、コマンドrplの方が覚えやすいでしょう。現在のディレクトリ内のすべてのファイルを再帰的に置換 (foo -> bar) します。
rpl -R foo bar .
ほとんどの Linux ディストリビューションではデフォルトで利用できませんが、インストールは簡単です (apt-get install rpl
または同様のもの)。
ただし、正規表現と逆置換、またはファイルの名前変更と検索と置換を含むより困難なジョブの場合、私が知っている最も一般的で強力なツールはreprenです。これは、私が以前に書いた小さな Python スクリプトです。厄介な名前の変更とリファクタリングのタスク。あなたがそれを好む理由は次のとおりです。
例については、READMEを確認してください。
これは実際には見かけよりも簡単です。
grep -Rl 'foo' ./ | xargs -n 1 -I % sh -c "ls %; sed -i 's/foo/bar/g' %";
簡単です。find、grep、xargs、sed、および awk をよく理解していれば、bash でのテキスト ファイルの操作に関しては、不可能なことはほとんどありません :)
2022年の答え。
https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#how-can-i-search-and-replace-with-ripgrep
rg foo --files-with-matches | xargs sed -i 's/foo/bar/g'
ripgrep が foo パターンを見つけたファイル内の「foo」のすべてのインスタンスを「bar」に置き換えます。sed の -i フラグは、ファイルをその場で編集していることを示し、s/foo/bar/g は、パターン foo の bar への置換を実行していること、およびこの置換をグローバルに実行していることを示します (各ファイルのパターン)。