500万ファイルを効率的にマージ

500万ファイルを効率的にマージ

間違った計画のため、私のディレクトリには500万を超えるファイルが含まれており、総容量は約20 GBです。各ファイルの上部には32行のゴミが含まれており、その後に不明な数の重要なデータ行があります。

すべての重要なデータを1つのファイルに統合したいと思います。

私はこれをやっています:

for i in $(find); do tail -n +32 $i >> ../all.txt; done

all.txtは毎秒約0.5MBだけ増加します。これを行うより速い方法はありますか?また、作業を完了する前にディスク容量が不足している可能性があるため、ファイルを削除すると便利です。 X

どんな提案にも感謝します。

ベストアンサー1

いつでもファイルを削除する必要がある場合、作成した内容はすでにクイック削除方法です。 1つの最適化は、をfind使用してファイルを一覧表示するのではなく、ファイルの内容を一覧表示するために使用できることです*。これは、ファイルが追加の処理時間を発生させることなくディレクトリリストに表示されるためですfind。つまり、次のように作成します。

for i in *; do tail -n +3 $i >> ../x; rm $i; done

ただし、マージを完了する前にそのアイテムを削除して、どのコンテンツがどのファイルから来たかを維持したい場合は、一度に解析して複数のアイテム(シェルで許可されている限り)を追跡する方法があります。これを行うコマンドは次のとおりです。

find . -exec tail -n +3 {} >> ../x +

最後に、一度に1つずつ複数のファイル名を一度に渡すように求められます+findこれにより、(呼び出されるインスタンスの数がはるかに少なくなるため)パフォーマンスが大幅に向上しますが、tail出力ファイルにはまだ次の内容があります。

==> ./filename <==

1つのファイルが終了し、次のファイルが起動するたびに印刷します。また、これらのファイルは削除されません。

少しの速度を犠牲にして上記の行を削除するには、次のように実行できます。

find . -exec awk 'FNR>32' {} + 

(コメントで提案してくれたdave_thompsonに感謝します)。

最後に、どの情報がどのファイルから来たのかを一覧表示する出力を好み、いつでも削除したい場合は、iruvarの答えを使用して2つの「」を「」\;+に置き換えることができます(私の元の答えは何をすべきか?を提供します。

おすすめ記事