ある条件は含まれ、他の条件は除外するファイルを見つける方法

ある条件は含まれ、他の条件は除外するファイルを見つける方法

ソースツリーがあり、特定の単語を含み、2番目の単語を含めてはいけないすべてのファイルを探しています。これは、新しいコードを含めるために古いファイルを更新する必要があるためです。

findを使用できることはわかっていますが、grepステートメントをリンクしようとすると、2番目のgrepステートメントが最初のgrepステートメントの結果を取得して迷子になるため、うまくいかないようです。

私は試した:

find . -type f -name "*.c" -exec grep -Hl "ABC" {} \; | grep -L "123"

これはまったく機能しません。どんな助けでも大変感謝します。

答え1

の終了ステータスは一致が見つかったかどうかを示すため、条件付き(必要な否定または)で直接テストできる必要がgrepあります。find!-not

find . -type f -name "*.c" \( -exec grep -q "ABC" {} \; ! -exec grep -q "123" {} \; \) -print

-q最初のゲームは自動的に終了します。ファイル名を印刷するようにしてgrepおくため、これについて聞く必要はありません。find

答え2

すでにGNU拡張を使用しているので:

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L 123

このファイルに対して他のタスクを実行するには、次のようにします。

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L --null 123 | xargs -r0 sh -c '
    for file do
      something with "$file"
    done' sh {} +

またはzsh以下を使用してくださいbash

find . -type f -size +2c -name "*.c" -exec grep -l --null ABC {} + |
  xargs -r0 grep -L --null 123 |
  while IFS= read -rd '' file; do
    something with "$file"
  done

答え3

複雑な制約の場合は、プログラミング言語であるAwkを使用することをお勧めします。

find -name '*.c' \
   -exec awk -v RS="\0" '/ABC/ && !/123/{print FILENAME}' {} \; 

関連情報