web-dev-qa-db-ja.com

異なる行に2つの文字列を含むファイルを見つける方法

実際の例は次のとおりです。Pythonファイルutil.py、そして関数名の1つをfooからbarに変更しました。関数名としてfooを使用している他のファイルがある可能性があり、それらは無関係です。

プロジェクト内のすべてのPythonファイルをfooからbarに更新したいので、次のようなインポートのファイルを検索したいと思います。

import project.path.util

または

from project.path.util import foo

fooへの呼び出し(次で始まるものなど):

foo(

ソリューションは空白に耐性がある必要があります。 grepを使用してそれぞれを検索できますが、組み合わせた検索についてはよくわかりません。任意の提案をいただければ幸いです。

6
Xiaoge Su

GNUツールを使用:

grep -rlZ --include='*.py' -e 'import project.path.util' \
                           -e 'from project.path.util import.*\bfoo\b' . |
  xargs -r0 sed -i 's/\bfoo\b/bar/g'

これは、grep

  1. 再帰的に検索します(-r
  2. 一致するファイルの名前を出力する(-l
  3. LF(-Z)の代わりにNULで区切られます
  4. '.py'で終わるファイルのみを考慮(--include='*.py'

一致するすべてのファイル(-i)がある場合は、その場で置換(xargs -r)を実行するようにsedに要求します。

5

検索したいディレクトリにいるとしましょう(どのサブディレクトリにも一致します):

 for i in `find . -type f -name '*.py' -exec grep -lr 'foo' {} +`; do sed -i 's/foo/bar/' $i; done

編集:

「damned_fools」のような文字を含む関数の一致を回避するために、\ bを使用してWordの境界に一致するように改善できます。

for i in `find . -type f -name '*.py' -exec grep -lr 'foo' {} +`; do sed -i 's/\bfoo\b/bar/' $i; done

参照:https://stackoverflow.com/questions/1032023/sed-whole-Word-search-and-replace

0
Aline

これで十分です。

/gfooのすべてのインスタンスをbarに置き換えます

find <Project root dir> -type f -exec sed -i "{}" -e 's/foo/bar/g' \;

変更を* .pyファイルのみに制限する場合:

find <Project root dir> -type f -name "*.py" -exec sed -i "{}" -e 's/foo/bar/g' \;

置き換えてはならないfooのインスタンスがある場合は、次の4つのケースに制限できます。

  • インポートfoo
  • モジュールインポートからfoo
  • def foo
  • foo

だがしかし

  • damned_foo(
  • damnedfoo(
  • damned1foo(
  • くそーfoo(

その場合、コマンドは次のようになります。

foo="foo";bar="bar";find <Project root dir>  -type f -exec sed -i "{}" \
-r -e "s/[^a-zA-Z0-9_\-]$foo\(/$bar\(/g" -e "s/def $foo/def $bar/g" \
-e "s/import $foo/import $bar/g" \;
0
UnX