すべてのパターンがファイルにあることを確認する

すべてのパターンがファイルにあることを確認する

patterns.txt私が1つあり、これらのパターンがそれぞれ特定のファイルに存在することを確認したいとします。

次のようにできます。

for pattern in $(cat patterns.txt); do 
  if ! grep -q "$pattern" file.txt; then
    echo "Error: missing pattern $pattern"
  fi
done
echo "All patterns found"

ただし、これはfile.txt各パターンを再検索する必要があるため非効率的です。潜在的に大きなパイプのストリーム内のファイルにパターンが見つからなかった場合、状況はそれほど単純ではありません。

grep確認する方法(または他のツール)がありますか?みんなパターンが存在するか?

答え1

cat file.txt | awk '
    NR == FNR {seen[$0] = 0; next} 
    {for (p in seen) if ($0 ~ p) seen[p]++} 
    END {
        for (p in seen) 
            if (seen[p] == 0) {
                missing++
                print "missing pattern", p
            } 
        if (missing == 0) print "all found"
        exit missing
    }
' patterns.txt -

command をcatテキストを生成するパイプに置き換えます。

答え2

これはうまく機能できます:

sort -u patterns.txt > sorted_patterns.txt # only once
diff -sq <(grep -o -f sorted_patterns.txt file.txt | sort -u) sorted_patterns.txt

パターンの代わりに固定文字列がある場合、これを使用するとはるかに高速に-Fなります。grep

あなたはできますまた使用cmp変えるdiff -s。少し速いかもしれませんが、欠けているものは表示されません。


すべてのパターンが見つからない場合は、次のように出力します。

Files /dev/fd/63 and /dev/fd/62 differ

またはすべてのパターンが見つかった場合:

Files /dev/fd/63 and /dev/fd/62 are identical

去る-qまでは分からないだろうすべて書いた。

2a3
> missing_word

答え3

grepPCRE拡張機能を使用してprintfコマンドの機能を使用すると、次のことができます。

<infile grep -qzP "(?s)$(printf "(?=.*?%s)" $(<pattern.txt))" &&
 echo 'all matched' ||
 echo 'one or more pattern(s) does not found'

すべてのモード(inどんな注文でも) が入力ファイルにあります。ネペレその後、テキストメッセージを送信all matchedそれ以外の場合はテキストとして出力されます。one or more pattern(s) does not foundエコーになります。

これはパターンを一致パターンとして使用します。たとえば、正しいパターンと一致するために&と一致し、pat[01]文字通り特殊文字をエスケープするように制御修飾子を変更します。pat0pat1pat[01]printf%s%q

<infile grep -qzP "(?s)$(printf "(?=.*?%q)" $(<pattern.txt))" &&
 echo 'all matched' ||
 echo 'one or more pattern(s) does not found'

関連情報