web-dev-qa-db-ja.com

別のファイルに存在しないファイルの行を見つける

2つのファイル(a.txtb.txtと言う)があり、どちらにも名前のリストがあります。すでに両方のファイルでsortを実行しています。

a.txtにはないb.txtの行を見つけたいと思います。

(私はこの質問の答えを見つけるのに多くの時間を費やしたので、将来の参考のためにそれを文書化します)

85
Sudar

使用する必要があるコマンドはdiffではなく、commです。

comm -23 a.txt b.txt

デフォルトでは、commは3列を出力します:左のみ右のみ両方-1-2、および-3スイッチは、これらの列を抑制します。

したがって、-23right-onlyおよびboth列を非表示にし、最初の(左)ファイルにのみ表示される行を表示します。

両方に表示される行を検索する場合は、-12を使用できます。これにより、左のみ列と右のみ列が非表示になり、 both列。

144
Sudar

commが行ごとに一致することを知らなかったため、単純な答えは私にはうまくいきませんでした。たとえば、file1に含まれている場合:

_Alex
Bill
Fred
_

File2には次が含まれます。

_Alex
Bill
Bill
Bill
Fred
_

次に、_comm -13 file1 file2_が出力します:

_Bill
Bill
_

私の場合、各ファイルでその行が何回発生したかに関係なく、file2のすべての文字列がfile1に存在することだけを知りたいと思いました。

解決策1:_-u_(一意)フラグを使用してsortに:

comm -13 <(sort -u file1) <(sort -u file2)

解決策2:(私が見つけた最初の「動作する」答え)from nix.stackexchange

_fgrep -v -f file1 file2_

File2にfile1にまったく存在しない重複行が含まれている場合、fgrepは重複行をそれぞれ出力することに注意してください。また、単一の(かなり大きい)データセットに対する単一のラップトップでの完全に非科学的なテストでは、ソリューション1(commを使用)がソリューション2(fgrepを使用して) )。

28
Johann

diffを使用すべきでないと言われた理由はわかりません。これを使用して2つのファイルを比較し、左側のファイルにはあるが右側のファイルにはない行のみを出力します。そのような行は<でdiffによってフラグが立てられるため、行の先頭でそのシンボルをgrepするだけで十分です。

diff a.txt b.txt  | grep \^\<
7
simonemainardi

ファイルがまだソートされない場合は、次を使用できます。

comm -23 <(sort a.txt) <(sort b.txt)
5
Basj