web-dev-qa-db-ja.com

Grepと交換の仕方

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

私はそれを見つけるためのコマンドがこのようになるかもしれないことを知っています:

grep 'string_to_find' -r ./*

しかし、どのようにしてstring_to_findのすべてのインスタンスを別の文字列に置き換えることができますか?

202
billtian

もう1つの選択肢は、findを使用してからsedに渡すことです。

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

私は答えを得ました。

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
142
billtian

あなたもこれに従うことができます..

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

これはカレントディレクトリを基準にして全てのファイルで文字列 ' windows 'を検索し、各ファイルで文字列が現れるたびに ' windows 'を ' linux 'に置き換えます。

31
Dulith De Costa

これは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

28
Marc Juchli

他の解決策は正規表現の構文を混ぜる。 both 検索および置換にPerl/PCREパターンを使用し、すべてのファイルの処理を回避するために、これは非常にうまく機能します。

grep -rlZP 'match1' | xargs -0r Perl -pi -e 's/match2/replace/g;'

match1match2は通常同一ですが、置換にのみ関連するより高度な機能を削除するためにmatch1を簡略化することができます。グループをキャプチャします。

翻訳:grep再帰的に、このPCREパターンにマッチするファイル名の中の特殊文字を保護するためにヌルで区切られたマッチするファイルをリストし、次にそれらのファイル名をヌル区切りリストを期待するxargsにパイプします名前を受け取り、Perlに各ファイルを書き換え、一致が見つかった行を置き換えます。

バイナリファイルも無視するには、Iオプションをgrepに追加します。

4
Walf

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

3
minopret

Gitレポジトリでfindsedを使用するときは十分に注意してください。バイナリファイルを除外しないと、このエラーが発生する可能性があります。

error: bad index file sha1 signature 
fatal: index file corrupt

このエラーを解決するには、あなたのnew_stringをあなたのold_stringに置き換えることによってsedを元に戻す必要があります。これは置き換えられた文字列を元に戻すので、問題の最初に戻ります。

文字列を検索して置き換える正しい方法は、バイナリファイルを無視するためにfindをスキップして代わりにgrepを使用することです。

sed -ri -e "s/old_string/new_string/g" $(grep -Elr --binary-files=without-match "old_string" "/files_dir")

@hobsのクレジット

3
tsveti_iko

ここに私がやることがあります:

find /path/to/dir -type f -iname "*filename*" -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'

これにより、/path/to/dirの下のファイル名にfilenameを含むすべてのファイルが検索され、見つかったすべてのファイルよりも、searchstringで行を検索し、oldnewに置き換えます。

0
tinnick

他の選択肢は単にglobstarと一緒にPerlを使うことでしょう。

shopt -s globstarで(またはどこででも).bashrcを有効にすると、** globパターンですべてのサブディレクトリとファイルを再帰的に一致させることができます。

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

-XフラグはPerlに "すべての警告を無効にする"よう指示します - これはディレクトリについて文句を言わないことを意味します。

Globstarでは、すべての子ファイルで拡張子sed -i 's/SEARCH/REPLACE/g' **/*.extを持つSEARCHREPLACEに置き換える場合にも、.extのようなことを実行できます。

0
GuiltyDolphin