ファイルAに含まれているが、ファイルBには含まれていない行を取得できるツールはありますか?たとえば、perlを使用して少し簡単なスクリプトを作成できますが、そのようなものが既に存在する場合は、これから時間を節約します。
ファイルAに含まれているが、ファイルBには含まれていない行を取得できるツールはありますか?たとえば、perlを使用して少し簡単なスクリプトを作成できますが、そのようなものが既に存在する場合は、これから時間を節約します。
回答:
はい。grep
テキスト文字列のファイルを検索するための標準ツールを使用して、あるファイルのすべての行を別のファイルから差し引くことができます。
grep -F -x -v -f fileB fileA
これは、fileBの各行をパターン(-f fileB
)として使用し、一致する(通常の正規表現ではなく)プレーンストリングとして処理することで機能します(-F
)。行全体で一致を強制的に発生させ(-x
)、一致しない行のみを出力します(-v
)。したがって、fileBの行と同じデータを含まないfileAの行を印刷しています。
このソリューションの欠点は、行の順序が考慮されていないことと、入力に異なる場所で重複する行があると、期待どおりの結果が得られない可能性があることです。その解決策は、などの実際の比較ツールを使用することですdiff
。これを行うには、ファイルの行の100%にコンテキスト値を持つdiffファイルを作成し、ファイルAをファイルBに変換する場合に削除される行だけを解析します(このコマンドはdiffも削除することに注意してください正しい行を取得した後のフォーマット。)
diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
-u
引数は、スペースが後に続かない限り、実際には数値のパラメーターを取ります。以前の方法の利点は、値の有無にかかわらず動作するため、出力ではなく返されたサブコマンドルーチンで何かを使用できることです。一方、大文字の「-U」には引数が必要です。
diff
パイプラインは、治療のおかげで動作します。
diff
、ファイル内の位置が考慮されることです。
答えは、比較するファイルの種類と形式に大きく依存します。
比較しているファイルがソートされたテキストファイルである場合、Richard StallmanとDavide McKenzieによって作成されたGNUツールが呼び出されcomm
、フィルタリングを実行できます。これはcoreutilsの一部です。
次の2つのファイルがあるとします。
$ cat a
1
2
3
4
5
$ cat b
1
2
3
4
5
6
ファイル内b
にないファイル内の行a
:
$ comm <(sort a) <(sort b) -3
6
comm
場合は+1 。残念ながら、comm
ソートされたファイルが必要です
<()
?それは動作し、私はそれを取得しますが、この奇妙さの名前はありますか?
comm
元々1973年頃、rmsではなく、Bell Labsの誰かによって書かれました。あなたはずっと後に来たGNU実装について言及しています。ここ数年、Unixユーティリティのさまざまな実装が行われてきました。
grepおよびcomm(with with sort)メソッドは、大きなファイルで長い時間がかかります。SiegeXとghostdog74は、Stack Overflowの2つのファイルのいずれかに固有の行を抽出するための 2つの優れたawkメソッドを共有しました。
$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2
$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2