両方のファイルを比較し、一致する行を印刷する必要があります。 file1ユーザー名がfile2(フィールド1)にある場合は、それを一致する新しいファイルに印刷したいと思います。
ファイル1.txt:
Hey123
Johnson
Hanny123
Fanny
(ファイル1は240MB - 20.000.000行)
ファイル2.txt:
Gromy123:hannibal
Hey123:groll
Hanny123:tronda9
Kroppsk:football23
(ファイル2は1.4GB - 69.000.000行)
予想される一致ライン出力:
Hanny123:tronda9
Hey123:groll
4時間努力しましたが、成功しませんでした。どちらのファイルも並べ替えられ、Join + 多数の grep/awk コマンドを試しました。私の最大の問題は、メモリが不足していることです。このように大きなファイルをどのように処理できるかを助けたいと思います。
ベストアンサー1
ファイルがソートされている場合(公開例は次のとおり)、簡単です。
join -t : File1.txt File2.txt
join
結合フィールドが同じ2つのファイルの行をペアにします。デフォルトでは、結合フィールドは最初のフィールドです。ただし、結合フィールドが繰り返されず、フィールドが順番に出力され、ペアリングできない行をスキップすることが、まさに欲しいものです。
ファイルがある場合は注意してください。Windowsラインターミネーター、各行の末尾に追加のキャリッジリターンがあるUnixシステムに表示されます。 CRはほとんど視覚的には見えませんが、join
他のテキストツールに関する限り、他の文字と同じです。つまり、すべてのフィールドはFile1.txt
CRで終わりますが、フィールドはFile2.txt
そうではないので一致しません。少なくとも、CRを削除する必要がありますFile1.txt
。
<File1.txt tr -d '\r' | join -t : - File2.txt
ファイルをソートする必要があります。そうでない場合は、ksh / bash / zshでプロセスオーバーライドを使用できます。 (必要に応じて追加してくださいtr -d '\r' |
。)
join -t : <(sort File1.txt) <(sort File2.txt)
通常のshにUnixバリアントがある場合/dev/fd
(ほとんどはい)、これを使用して2つのファイル記述子を介して2つのプログラムの出力をパイプ処理できます。
sort File2.txt | { sort File1.txt | join -t : /dev/fd/0 /dev/fd/3; } 3<&1
元の順序を維持する必要があり、File1.txt
結合フィールドで並べ替えない場合は、元の順序を記憶するように行番号を追加し、結合フィールドで並べ替え、結合し、行番号で並べ替え、行番号を削除します。 (他のファイルの順序を維持したい場合は、同様のことができます。)
<File1.txt nl -s : |
sort -t : -k 2 |
join -t : -1 2 - <(sort File2.txt) |
sort -t : -k 2,2n |
cut -d : -f 1,3