web-dev-qa-db-ja.com

複数のファイルを作成する効率的な方法

私は最大のiノードを使用しているfindディレクトリをテストしており、テスト中に実行しました

touch test_{1..1391803}.txt

しかし、それは私にエラーを与えます"-bash: /usr/bin/touch: Argument list too long"、今はコマンドの下で実行していますが、ヒュー時間がかかるようです

Ruby -e '1.upto(1391803) { |n| %x( touch "test_#{n}.txt" ) }'

だから問題は:短時間で複数のファイルを作成する方法はありますか?ループごとに1つのlacファイルをタッチする必要がありますか?

テスト結果:

No。1

[root@dc1 inode_test]# time seq 343409 | xargs touch

real    0m7.760s
user    0m0.525s
sys     0m4.385s

No。2

[root@test-server inode_test]# time echo 'for (i=1;i<=343409;i++) i' | bc | xargs touch

real    0m8.781s
user    0m0.722s
sys     0m4.997s

[root@test-server inode_test]# time printf '%s ' {1..343409} | xargs touch

real    0m8.913s
user    0m1.144s
sys     0m4.541s

No。4

[root@test-server inode_test]# time awk 'BEGIN {for (i=1; i<=343409; i++) {printf "" >> i; close(i)}}'

real    0m12.185s
user    0m2.005s
sys     0m6.057s

No。5

[root@test-server inode_test]# time Ruby -e '1.upto(343409) { |n| File.open("#{n}", "w") {} }'

real    0m12.650s
user    0m3.017s
sys     0m4.878s
7
Rahul Patil

制限は、コマンドのexecutionの引数のサイズにあります。したがって、オプションは、引数を減らしてコマンドを実行することです。たとえば、小さいバッチを実行する場合はxargsを使用して、制限(ulimit -s 100000(Linuxの場合)、何も実行しない(シェルですべて実行する)か、ファイルを作成するツールでリストを作成します。

zshksh93bash

printf '%s ' {1..1391803} | xargs touch

printfは組み込みなので、execがないため、制限に達していません。 xargsは、touchに渡された引数のリストを分割して、制限を超えないようにします。シェルは最初にリスト全体を作成し(特にbashを使用すると処理が遅くなります)、メモリに格納してから印刷する必要があるため、これはまだ効率的ではありません。

seq 1391803 | xargs touch

(あなたがseqコマンドを持っていると仮定して)より効率的でしょう。

for ((i=1; i<=1391803; i++)); do : >> "$i"; done

すべてがシェルで行われ、メモリに大きなリストは保存されません。おそらくbashを除いて、比較的効率的です。

POSIXly:

i=1; while [ "$i" -le 1391803 ]; do : >> "$i"; i=$(($i + 1)); done

echo 'for (i=1;i<=1391803;i++) i' | bc | xargs touch

awk 'BEGIN {for (i=1; i<=1391803; i++) {printf "" >> i; close(i)}}'
12

touchが処理できる引数の最大数によって制限されています。最善の策は、ループを使用することです。ただし、Rubyを実行する必要はありません。

for i in $(seq 1391803); do touch test_${i}.txt; done

別の方法としては、数を100などのチャンクに分割し、それらを一度にtouchにフィードすることもできます。

i=1; while ((i<=1391803)); do touch $(seq $i $((i+99))); i=$((i+100)); done
3
devnull