grepに一致するすべてのファイルの文字列を検索して置換しようとしています:
grep -n 'foo' *
次の形式で出力が表示されます。
[filename]:[line number]:[text]
grepから返されたファイルごとにfoo
、bar
。に置き換えてファイルを変更したいと思います。
grepに一致するすべてのファイルの文字列を検索して置換しようとしています:
grep -n 'foo' *
次の形式で出力が表示されます。
[filename]:[line number]:[text]
grepから返されたファイルごとにfoo
、bar
。に置き換えてファイルを変更したいと思います。
回答:
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 -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
見つけるためには、ファイルが一致されていたショーに便利です。これはすべて、システム上のこれらのツールの正確なバージョンによって異なります。
find
コマンドに開始するディレクトリを指定する必要があります。たとえば、find . -name '*.html'
またはfind directoryname/ -name '*'
。
sed -ie 's/foo/bar/g' *
あなたがいる場合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/' *
for i in *; do ...
冗長であるため、sedはファイルのリストを引数として取ることができます。
for i in *; do; sed -i 's/foo/bar/g' "$i"; done
これは、perlやfindを使用せずにgrepを使用して機能します。
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
-i
他のOSでは動作しないとは知りませんでした。私のためにubuntuで動作します。
xargs
マンページ(Ubuntu)には、これ-i
は非推奨であり、-I
代わりに使用すると書かれています。そこで、我々は言う必要があります:grep -rli 'old-word' * | xargs -I filepath sed -i 's/old-word/new-word/g' filepath
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スクリプトです。厄介な名前の変更とリファクタリングのタスク。あなたがそれを好むかもしれない理由は次のとおりです:
これは実際には見た目よりも簡単です。
grep -Rl 'foo' ./ | xargs -n 1 -I % sh -c "ls %; sed -i 's/foo/bar/g' %";
簡単なピーシー。find、grep、xargs、sed、awkをよく理解していれば、bashでのテキストファイルの操作に関してはほとんど不可能なことはありません:)
Can't open Untitled: No such file or directory, <> line 5
「無題のフォルダ/file.txt」を試すとき。