合計20GBを超える1万個以上のファイルがあり、それらを1つのファイルに連結する必要があります。
より速い方法はありますか
cat input_file* >> out
?
推奨される方法はbashコマンドです。Pythonは、かなり遅くなければ受け入れられます。
合計20GBを超える1万個以上のファイルがあり、それらを1つのファイルに連結する必要があります。
より速い方法はありますか
cat input_file* >> out
?
推奨される方法はbashコマンドです。Pythonは、かなり遅くなければ受け入れられます。
回答:
いや、猫はこれを行う最善の方法です。この目的のためにCで書かれたプログラムが既にあるのに、なぜpythonを使用するのですか?ただし、xargs
コマンドラインの長さを超えてARG_MAX
おり、複数必要な場合に使用することを検討してくださいcat
。GNUツールを使用すると、これはすでにあるものと同等です。
find . -maxdepth 1 -type f -name 'input_file*' -print0 |
sort -z |
xargs -0 cat -- >>out
find
を介してパイプされるためsort
です。これがないと、ファイルは任意の順序でリストされます(ファイルシステムで定義され、ファイル作成順序になる可能性があります)。
bash
グロブとは異なる動作をする可能性があることです。そうしないと、期待どおりに動作する、xargs
またはcat
動作しないケースは見当たりません。
xargs
呼び出しますcat
。
最初に出力ファイルにスペースを割り当てると、システムが書き込みごとに割り当てを更新する必要がなくなるため、全体的な速度が向上する場合があります。
たとえば、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個のファイルがある場合、最初のファイルが非常に大きい場合を除き、おそらくそれほど違いはありません。
そこにすべてのファイルを(REF-コピーすることを一般化するAPIだBTRFS_IOC_CLONE_RANGE
ioctl
)が、あなたがCでそれをしなければならないと思いますので、私は、そのAPIをさらす任意の有用性を見出すことができませんでした(またはpython
あるいは他の言語は、彼らが任意呼び出すことができます提供ioctl
秒) 。
ソースファイルがスパースであるか、NUL文字の大きなシーケンスを持っている場合、(GNUシステム上で)スパース出力ファイルを作成できます(時間とディスク容量を節約します)。
find . -maxdepth 1 -type f -name 'input_file*' -print0 |
sort -z | xargs -r0 cat | cp --sparse=always /dev/stdin out
>
も>>
、しかし1<>
私は、書き込みに言ったように、ファイル。
<>
は、標準のBourne / POSIX読み取り/書き込みリダイレクト演算子です。詳細については、シェルマニュアルまたはPOSIX仕様を参照してください。デフォルトではfd
ある0
ため<>
、オペレータ(<>
の略である0<>
ように、<
短いためである0<
と>
短いために1>
必要なので、)1
明示的にリダイレクトstdoutに。ここでは、read + write(O_RDWR
)が必要なほど多くはありませんが、O_TRUNC
(のように>
)割り当てたばかりの割り当てを解除する必要はありません。
dd
リーディングを使用して、またはリーディングを介してシークできます。
fallocate
ますが、extraのオーバーヘッドを打ち消すケースが多いとは思いませんfind
。btrfs
確かにいくつかの興味深い可能性を開きます。
find
。シェルグロブと同じようにファイルをソートしません。