「Ungrep」-一致しないパターン


13

次のことを行うコマンドまたはスクリプトを探しています-指定:

file1.txt:

abcd
efgh 
ijkl
mnop

file2.txt:

123abcd123
123efgh123
123mnop123

私はこのようなことをするコマンドが欲しいです:

ungrep file1.txt file2.txt

次を返します。

ijkl

言い換えれば、file2.txtのgrepで結果を返さないfile1.txtの行を提供しています。file1.txtを反復処理し、各行のfile2.txtをgrepして結果を保存し、結果が空の行を出力することでこれを実行できることを知っていますが、これを行うためのより効率的な方法を期待していました。

回答:


18

GNU grepでは、次のように動作するはずです。この-fオプションを使用しfile1.txtて、「パターンファイル」として渡しますが、データファイルとして2度目に渡します。-o一致する部分のみを報告するために使用します。最後に、1回だけ一致する単語を抽出します。これらはfile1.txt、で一致するものが見つからない行に対応しfile2.txtます。

grep -h -o -f  file1.txt file2.txt file1.txt | sort | uniq -u
ijkl

非常に良い説明。ありがとう、+ 1。
unxnut

4
grepのトリッキーなしで同じ効果を得ることができsort file1.txt <(grep -of file1.txt file2.txt) | uniq -uますが、ソリューションのように、これは実際にパターンファイルに正規表現のメタキャラクターが含まれていない場合にのみ機能します。
リチ

非常に良い点です@rici、
iruvar

2
改善:grep -oFf file1.txt file2.txt | sort file1.txt - | uniq -u
ステファンシャゼラス

10

次のawkようにできます:

awk '
  NR == FNR {w[$0]; next}
  {for (i in w) if (index($0,i)) delete w[i]}
  END {for (i in w) print i}' file1.txt file2.txt

を使用することでindex、正規表現に一致するのではなく、部分文字列を探しています。

一致するものが見つかるとすぐに配列から単語を削除するため、不必要な検索を回避します。


1
私はこれを受け入れるだけです。O(n log n)ソートを呼び出さず、パターンに正規表現のメタ文字が含まれている場合に異常に失敗せず、正規表現をサポートするように拡張できます。
カズ

単純に評価w[$0]すると、キーが配列に追加されるという副作用があるとは信じられません。
カズ

1
@Kaz、はい、それは混乱を招く可能性があります。また、たとえば、if (a[$1])代わりに行うことによって、意図せずに配列要素を割り当てていない多くのスクリプトが見つかりif ($1 in a)ます。それはすべての場合ですawkオリジナルのawkとを含むnawk当てはまりますが、昨日標準を見て、指定されたものが見つかりませんでした。
ステファンシャゼラス

1
@Kaz POSIXの引用は次のとおりです。「アプリケーションは、in演算子で使用される多次元インデックスが括弧で囲まれていることを確認します。特定の配列要素の存在をテストするin演算子は、その要素を存在させません。存在しない配列要素への他の参照により、自動的に作成されます。」ここ から1つまたは2つの段落をスクロールして見つけることができます
jw013

1
file1巨大ではない限り(巨大な値の場合)、このソリューションは並べ替えを必要とせず、file2はるかに効率的であることが期待されるため、このソリューションを好むでしょう。
jw013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.