単語セット(AAAA&(BBB | CCCCC)&〜DDDなど)を含むテキストファイルを検索するにはどうすればよいですか?

単語セット(AAAA&(BBB | CCCCC)&〜DDDなど)を含むテキストファイルを検索するにはどうすればよいですか?

比較的複雑な基準を満たすファイルを見つける必要があります。たとえば、次の条件をすべて満たすすべてのファイルを検索したいとします。

  • AAAAという言葉が含まれています。
  • BBBまたはCCCCC(両方可能)という単語が含まれています。
  • DDDという単語は含まれていません。

単語は、順序に関係なく他の行(または同じ行)に表示できます。

find結合されたソリューションがありますが、egrep明確ではありません。

find . \( -type f -and -exec egrep -q 'BBB|CCCCC' {} \; \
     -and      -exec egrep -q AAAA {} \; \
     -and -not -exec egrep -q DDD {}  \;    \) -print

この問題を解決するより良い方法はありますか?

ベストアンサー1

あなたの解決策は仕事にとって非常に明確であるようです。ただし、ファイルごとに3つのプロセスが作成されるため、遅くなります。私の考えでは、Awkはここにもっと適していると思います。なぜなら、ARG_MAXが許可するようにファイル全体のバッチを一度に読み取ることができるから{} +です{} \;

GNU awk:

find . -type f -exec gawk '
    BEGINFILE{c1=c2=c3=0}
    /AAA/       {c1=1}
    /BBB/||/CCC/{c2=1}
    /DDD/       {c3=1; nextfile}
    ENDFILE{if(c1 && c2 && !c3)print FILENAME}
' {} +

POSIX * :

find . -type f -exec awk '
    FNR==1{
        if(NR>1 && c1 && c2 && !c3)print f
        c1=c2=c3=0
        f=FILENAME
    }
    /AAA/       {c1=1}
    /BBB/||/CCC/{c2=1}
    /DDD/       {c3=1; nextfile}
    END{if(c1 && c2 && !c3)print f}
' {} +

*実はnextfileまだPOSIXではありませんが以下の規格により承認された。。 POSIX Issue 7コンプライアンスのためにそれらを削除できます。結果は同じですが、パフォーマンスに影響します。


ノート:awkにファイルを読み取る権限がない場合は終了します。 GNU Findでこの-readableフラグを追加すると、これを防ぐことができます。 GNU Findが利用できない場合は、Testを追加のフィルタとして使用できます。

find . -type f -exec test -r {} \; -exec awk '
    ...
' {} +

ただし、各ファイルのテストを生成するとパフォーマンスが低下します。


追加資料:

おすすめ記事