合計20GBを超える10k以上のファイルがあり、1つのファイルに連結する必要があります。
より速い方法はありますか
cat input_file* >> out
?
推奨される方法はbashコマンドです。Pythonも、かなり遅くない場合でも受け入れられます。
いいえ、猫は確かにこれを行うための最良の方法です。なぜpythonを使用して、この目的のためにすでにCで書かれたプログラムがあるのですか?しかし、コマンドラインの長さがARG_MAX
を超えており、必要な場合にxargs
複数のcat
。GNUツールを使用すると、これはすでに持っているものと同等です:
find . -maxdepth 1 -type f -name 'input_file*' -print0 |
sort -z |
xargs -0 cat -- >>out
最初に出力ファイルにスペースを割り当てると、システムがすべての書き込みの割り当てを更新する必要がないため、全体的な速度が向上する場合があります。
たとえば、Linuxの場合:
size=$({ find . -maxdepth 1 -type f -name 'input_file*' -printf '%s+'; echo 0;} | bc)
fallocate -l "$size" out &&
find . -maxdepth 1 -type f -name 'input_file*' -print0 |
sort -z | xargs -r0 cat 1<> out
もう1つの利点は、十分な空き領域がない場合、コピーが試行されないことです。
btrfs
の場合、copy --reflink=always
最初のファイル(これはデータのコピーがないことを意味するため、ほとんど瞬時に実行されます)に残りを追加します。 10000個のファイルがある場合、最初のファイルが非常に大きくない限り、おそらく大きな違いはありません。
すべてのファイルを参照コピーするためにそれを一般化するAPIがあります(BTRFS_IOC_CLONE_RANGE
ioctl
)ですが、そのAPIを公開しているユーティリティが見つからなかったため、C(またはpython
または他の言語で任意のioctl
s)。
ソースファイルがスパースであるか、NUL文字のシーケンスが大きい場合、(on GNU systems)を使用してスパース出力ファイル(時間とディスク領域を節約)を作成できます。
find . -maxdepth 1 -type f -name 'input_file*' -print0 |
sort -z | xargs -r0 cat | cp --sparse=always /dev/stdin out