複数のファイルから重複した行をすばやく削除

複数のファイルから重複した行をすばやく削除

各(データ)行が一意である必要がある大量のデータがあります。

フォルダに多くのファイルがあることはすでに事実です。サイズは約15GBで、約170個のファイルに分かれており、合計1,000,000本のラインがあります。このフォルダをと呼びますfoo

2番目のフォルダ(bar)にはより多くのデータが含まれます。つまり、ファイルごとに1つのエントリのみが含まれます。両方のファイルの交差部分がbar必ず空である必要はありません。各ファイルには約15,000行があります(そしてその中には何千ものファイルがありますbar)。

今私は使っています。

awk 'NR==FNR{a[$0]=$0;next}!a[$0]' foo/file bar/file > tmp
mv tmp bar/file

すべてのファイルを繰り返しfoobarfoo空の場合はループを解除しますbar/file。ロック(複数のノードで)と並列実行(各ノードで)を使用して並列化しました。しかし、まだ時間がかかります。

パフォーマンス向上の可能性は何ですか?のファイルの理想的なファイルサイズは何ですかfoo?もちろん、これはマシン(RAM/CPU/ストレージ)によって異なりますが、ここで良い経験則は何ですか?

長すぎます。:合計に複数回表示されるデータ行をfoo含む、一意のデータ行を含めます。bar重複したアイテムを削除してマージできます。barfoobarfoo

【書き直す】空行なし[/直す]

答え1

あなたの質問を理解したかどうかはわかりませんが、コードは次のように最適化される可能性があります。

awk '!x{a[$0];next}; !($0 in a)' foo/file x=1 bar/file > tmp

(空行や「0」と解釈される行に問題があるようです。)

ファイルがソートされたら、次のことができます。

comm -13 foo/file bar/file > tmp

そうでない場合(ksh93.zshまたはbash構文):

comm -13  <(sort foo/file) <(sort bar/file) > tmp

(awkソリューションより必ずしも高速ではありません)

また、特にGNU awkの場合、ロケールをC / POSIXに設定すると、より良いパフォーマンスが得られます。

LC_ALL=C awk ...

答え2

サイズが数MBしかないファイルが複数あります。次のように試してみました。

sort *.csv | uniq -d 

これにより、ファイルに重複レコードが提供され、出力を単一のファイルにリダイレクトして重複レコードを取得でき、削除を使用するとすべての一意の-dレコードが提供されます。

関連情報