2013-03-14 22 views
147

ディレクトリ内のすべてのファイルとサブディレクトリ内の指定された文字列を再帰的に検索し、この文字列を別の文字列に置き換える必要があります。grepとreplaceする方法

grep 'string_to_find' -r ./* 

しかし、私は別の文字列でstring_to_findのすべてのインスタンスを置き換えることができますか:

私は、コマンドが、それは次のようになります見つけることがいることを知っていますか?

+0

私はgrepがこれを行うことはできません(私は間違っている可能性があります)。より簡単な方法は、sedやperlを使って置換えすることです。 –

+1

'sed -i 's /.* substring。*/replace /''を使用してみてください。 –

+1

@Eddy_Emこれは、行全体をreplaceに置き換えます。グループ化を使用して、部分文字列の前後の行の部分を取得し、置換行にその部分を配置する必要があります。 – JStrahl

答えて

1

通常はgrepではなく、sed -i 's/string_to_find/another_string/g'またはperl -i.bak -pe 's/string_to_find/another_string/g'となります。

102

私は答えを得ました。

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g' 
+11

これは、一致するファイルを2回スキャンします。一度 'grep'でスキャンし、' sed '。 'find'メソッドを使うほうが効率的ですが、このメソッドはうまくいきます。 – cmevoli

+24

OS Xでは 'sed -i '/ str1/str2/g''を' sed -i ""'/str1/str2/g "に変更する必要があります。 – jdf

+2

@jdfなぜですか? – chishaku

158

もう1つの方法は、findを使ってsedに渡すことです。

find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \; 
+24

OS X 10.10ターミナルでは、パラメータ '-i'に対する適切な拡張文字列が必要です。たとえば、 'find/path/to/files -type f -exec sed -i '" "s/oldstring/new string/g" {} \; 'とにかく空の文字列を指定すると、 ... – Eonil

+5

「sed:REエラー:不正なバイトシーケンス」が表示されるのはなぜですか?そして、はい、私はOS X用の '-i" "を追加しました。そうでなければ動作します。 – taco

+0

私はmacOS 10.12で不正なバイトシーケンスの問題を抱えていました。この質問/回答が私の問題を解決しました:http://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac-os-x 。 – abeboparebop

25

これは、OS X上で私にとって最高の作品:

grep -r -l 'searchtext' . | sort | uniq | xargs perl -e "s/matchtext/replacetext/" -pi 

出典:http://www.praj.com.au/post/23691181208/grep-replace-text-string-in-files

+0

これは完璧です! ag: 'ag" search "-l -rとも動作します。 |並べ替え|ユニーク| xargs perl -e 's/search/replace' -pi' –

+1

'sort -u'は' sort |を置き換えることができます。 uniq' –

+0

@sebastiankellerあなたのPerlコマンドには最後のスラッシュがありません。これは構文エラーです。 – tripleee

0

別のオプションは、ちょうどglobstarでPerlを使用することです。あなたの.bashrc(または場所)でshopt -s globstarを有効にする

**グロブパターンは、再帰的にすべてのサブディレクトリとファイルを一致させることができます。

したがって、perl -pXe 's/SEARCH/REPLACE/g' -i **を使用すると、再帰的になります SEARCHREPLACEに置き換えます。

-Xフラグはperlに「すべての警告を無効にする」と指示します。つまり、 はディレクトリについて不平を言うことはありません。

globstarはまた、あなたが拡張子.extとすべての子ファイルでREPLACESEARCHを交換したい場合は、sed -i 's/SEARCH/REPLACE/g' **/*.extのようなものを行うことができます。

+0

* "もう一つの選択肢は、globstarでperlを使うだけです..." * - SolarisのようなPosixyのマシンではありません。だから私は特に 'grep'と' sed'を探しているのです。 – jww

19

あなたも、このように従うことができる。..

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g' 

これは、現在のディレクトリにすべてのファイルの相対で「」という文字列を検索し、「窓を交換します 'に' linux 'と入力します。

+2

'grep'は、変更すべきでないファイルがある場合にのみ有用です。すべてのファイルで 'sed'を実行するとファイルの変更日が更新されますが、一致するものがなければ内容は変更されません。 – tripleee

+0

@treepleee:* ...でも[sed]は一致するものがない場合は内容を変更しないでください "*。-iを使用する場合、' sed'はそれが触れるすべてのファイルのファイル時間を変更する"CRLF"は全て "LF"に変更されているので、GitリポジトリのWindowsでは 'sed'を使用しません。 – jww

3

他の解決策では、正規表現の構文が混在しています。 検索の両方のためのPerl/PCREのパターンを使用して交換して、すべてのファイルの処理を回避するために、これは非常にうまく機能:

match1match2は、通常は同じですが、 match1は、より高度な機能を削除するために簡略化することができる
grep -rlZP 'match1' | xargs -0r perl -pi -e 's/match2/replace/g;' 

こと置換にのみ関連している、例えばキャプチャグループ。

翻訳:grep再帰的にファイル名の特殊文字を保護するためにnulで区切られたファイルをリストし、このPCREパターンにマッチしたファイルをリストし、それらのファイル名をヌル区切りのリストを期待しているxargsにパイプします。名前がなければ何でもし、perlに各ファイルを書き換えさせて、一致するものが見つかった場合は行を置き換えます。

grepIオプションを追加すると、バイナリファイルも無視されます。

+0

Perl自体はファイルを再帰的に処理することができます実際には、 '' find2perl'(https://perldoc.perl.org/5.8.8/find2perl.html)のツールがあります。このツールはPerlに付属しています。このようなことは 'xargs'トリッキーなしに行われます。 – tripleee

+0

@tripleee 'find'はファイルの内容を検索しません。その点は、Perlプログラムを書くことなく一致するファイルだけを処理することです。 – Walf

-3

&は、ファイル のviのモードに置き換える構文は次のとおりです見つける: :%は、S/WORDに見つける-HERE /置き換え-Wordを-ここ/ gの

OR :%sの/ FindMe/ReplaceME/gで

置換コマンドは、あなたの要件に応じて使用することができます。

関連する問題