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

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

実際の例:Pythonファイルがあり、関数名util.pyの1つを 。関数名として使用される他のファイルがある可能性がありますが、これは関係ありません。foobarfoo

私のプロジェクトのすべてのPythonファイルをからに更新したいと思います。したがって、foobarのようなインポートされたファイルを検索したいと思います。

import project.path.util

または

from project.path.util import foo

次に始まるすべてのfoo通貨:

foo(

ソリューションは空白を許可できる必要があります。それぞれを使用して検索できますが、grep検索を組み合わせることについてはわかりません。どんなアドバイスも本当にありがとうございます。

答え1

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. -ZLF( ) の代わりに NUL で区切る
  4. '.py'( --include='*.py') で終わるファイルのみを考慮してください。

一致するすべてのファイル(存在する場合)でsed内部置換()を実行する必要があります。-ixargs -r

答え2

これはうまくいきます。

/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つのケースに制限できます。

  • 輸入金持ち
  • モジュールからインポート金持ち
  • 定義金持ち
  • 金持ち

しかし、

  • くそ_フー
  • クソ金持ち(
  • くそ 1foo(
  • クソ金持ち(

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

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" \;

答え3

検索したいディレクトリにあるとします(すべてのサブディレクトリとも一致します)。

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

編集する:

"damned_fools"などの文字を含む関数の一致を回避するには、\ bを使用して単語の境界を一致させるように改善できます。

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

関連情報