あるファイルの行が別のファイルのデータサブセットであることを確認する

あるファイルの行が別のファイルのデータサブセットであることを確認する

file1.txt次のデータを含むファイルがあります。

MIME_HTML_ONLY
SUSPICIOUS_RECIPS
SORTED_RECIPS
HFILTER_HELO_5

他のファイルにはfile2.txt次の行があります。

HFILTER_FROM_BOUNCE FORGED_OUTLOOK_HTML
SORTED_RECIPS HFILTER_HELO_5
MIME_HTML_ONLY HFILTER_FROM_BOUNCE
SUSPICIOUS_RECIPS ANY_OTHER_WORD
:
:

file2.txt行のすべての単語が現在のデータのサブセットであるデータのすべての行を検索したいと思います。file1.txt

例えば出力上記は次の行でなければなりません。 SORTED_RECIPS HFILTER_HELO_5

これで個々の行を繰り返し読み、file2.txtそれがのサブセットであることを確認できますfile1.txt。ただし、1000行の異なる行に対してこれを行う必要がありますfile1.txt's。したがって、file2.txtすべての行に対してループを繰り返すのfile1.txtは非常に遅いです。これを行うために使用できる効率的な方法はありますかawk sed grep

ベストアンサー1

awk 'FNR == NR && $0 !~ /^[[:blank:]]*$/ { Dict[$0] = 1 }
     FNR != NR {
        i = 1
        while( i <= NF && Dict[ $i] == 1) i++
        if( i > NF) print
        }
    ' File1.txt File2.txt
  • 普遍的で、file2の各行のフィールド/単語数に依存しません。
  • 両方のファイルのソートされたコンテンツとソートされていないコンテンツを処理します。
  • メモリを使用した最初のファイルのロード辞書だから、多くの単語を検証したい場合は、最善ではないかもしれません。
  • awkに提供されるファイルの順序は必須です。
    • 最初は事前参照です。
    • その他(少なくとも1つ)はフィルタリングするファイルです。

コンセプト:

  • 値をインデックスとして使用して、配列内の各単語をロードします。
    • 値1を使用します(割り当てられていない場合、デフォルトは0です)。
    • 最初のファイルで[ここでFNR(ファイルレコード番号)= NR(ファイルが最初に開かれた後のレコード番号)、デフォルトではレコードはawkの1行です]
    • 空白行にフィルタがあります(文字がないか空白のみがあります)。
  • カウンタ初期化(i)
  • 各フィールド(スペース区切り文字のため、デフォルトではここにある単語)を辞書の対応するフィールドと比較します。存在する場合(値= 1)、次のフィールドにループしてカウンタ(i)をインクリメントします。
  • ループの後、カウンタ(i)がフィールド(単語)の数より大きい場合、すべての単語が一致し、その行が印刷されます。
  • 次の行項目で繰り返す

おすすめ記事