一致する行のない入力パターンを印刷するには?

一致する行のない入力パターンを印刷するには?

パターンが一致するファイルを見つけるには、このgrepコマンドがあります。

grep -oiE 'pattern1|pattern2|pattern3|pattern4' *pattern_in_a_filename* | sort -u

出力:

file_one:pattern1
file_two:pattern2
file_two:pattern3

私が望むのは、pattern4次の例のように見つからないステートメントを出力することです。

file_one:pattern1
file_two:pattern2
file_two:pattern3
pattern4 not found

私は何千ものパターンを作っていますが、これは私たちの仕事に必要な重要なデータなので、すぐに完了する必要があります。

答え1

これをしなければならないクイックできるだけ

仕事を早く終わらせたいですか?

発見する並列処理次のGNUを適用してくださいparallel解決策:

正しい方法は、すべてのパターンをファイル(たとえばpatterns.txt

主な仕事:

cat patterns.txt | parallel -j 0 --no-notice 'grep -Hoi {} /path/to/files/* || echo "{} not found"' | sort -u
  • -j N- ポジション数。Nジョブを並列に実行します。0できるだけ意味を与えます。デフォルトは100%で、これはCPUコアごとに1つのタスクを意味します。

上記のコマンドはすべての項目を検索します。模様patterns.txtすべてのファイルから並列。

テストしてみると2CPUコアには、いくつかのパターンのリストと、それぞれ641Mbのいくつかのcsvファイルが含まれています。私は薬を持っています。470%連続処理と比較して時間速度が向上する。
コンピュータにCPUコアが多いほど、より高速なパフォーマンスが得られます。

結論を出す...

https://www.gnu.org/software/parallel/man.html

答え2

このツールはgrepパターンごとにファイルを検索します。これは、パターンが入力でファイルが出力であることを意味します。つまり、grepで見つけることができるのはパターンではなくファイルだけという意味です。

一致するパターンを含まないファイルを見つけるには、を使用する必要があります-v。これには2回の呼び出しが必要です。

例:

$ echo a > xa
$ echo ab > xab
$ echo c > xc
$ { grep -oiE 'a|b' x*; grep -vl -E 'a|b' x*; } | sort -u
xa:a
xab:a
xab:b
xc

一致しないパターンを見つけるには、パターンを入力として提供し、検索結果をパターンとして提供する必要があります。一致項目のリストはパターンになり、パターンは検索する必要があるデータになります。

これが前の例のファイルパターンであると仮定します。

$ pattern='a|b|d'

次に、一致するパターンのリストを配列に保存します。

$ found=($(grep -hoiE "$pattern" x* | sort -u))

これにより、配列が新しいモードに変換されます。

$ new_pattern="$(IFS='|' ; echo "${found[*]}")"

これにより、生のスキーマがデータに変換されます。

$ data="${pattern//|/$'\n'}"

一致しないパターンのリストは次のとおりです。

$ grep -viE "$new_pattern" <<< "$data"
d

答え3

期待を達成する方法は次のとおりです。何千ものパターンがあると言われたので、模様ファイルから直接渡すよりもはるかに優れています。模様到着するgrep。コマンドは次のとおりです。

grep -oif ../patt_file file* && 
    printf "%s Not Found.\n" $(grep -vFxf <(grep -oihf ../patt_file file*) \
    <(< ../patt_file))

一致しないために模様ファイル自体は、入力があるディレクトリ以外のディレクトリpatt_fileに移動する必要があります。infiles*

答え4

sh以下は必要な結果を生成するスクリプトです。

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* | sort -u > /path/to/foundFiles.txt 

while read -r LINE
do
    grep -F "$LINE" /path/to/foundFiles.txt
    if [ $? -eq 1 ]
    then
        echo "$LINE" not found
    fi
done < /path/to/patterns.txt

このスクリプトでは、あなたの出力あなたの grepファイルに保存found.txtし、パターンをファイルに保存します/path/to/foundFiles.txt

ご覧のとおり、ループは欠落している内容を追加しながらgrepファイルの同じ内容を生成します。found.txt"$pattern" not found

また、あなたの場合の2番目のアプローチを考案しました。

#!/bin/sh

grep -f /path/to/patterns.txt /path/to/*_856_2017* |
    sort -u > /path/to/foundFiles.txt

comm -23 /path/to/patterns.txt /path/to/foundFiles.txt |
    xargs -L 1 -I {} echo {} not found > /path/to/notFoundFiles.txt

cat /path/to/foundFiles.txt /path/to/notFoundFiles.txt > /path/to/finalList.txt

この場合、これが機能するpatterns.txtにはすでにソートされている必要があります。comm

このコマンドは、2つのファイルを比較し、見つからないパターンのリスト(引数)commに表示される行のみを返します。patterns.txt-23grep

次に、xargs各行(-L 1)をつかみ、{}「見つかりません」が追加された対応する行()をエコーし​​ます。結果はファイルxargsにリダイレクトされます。notFoundFiles.txt

最後に、findFiles.txtとnotFoundFiles.txtをfinalList.txt

関連情報