時間 generateUserData.sh テスト {0..1000}

時間 generateUserData.sh テスト {0..1000}

いくつかの実験のために大容量ファイルを生成したいと思います。

これは私のスクリプトです。ファイルを作成して変数として読み込み、ループ内で定義された回数だけファイルに書き込もうとします。

#! /usr/bin/env bash

set -e
set -u

< /dev/urandom tr -dc "\t\n [:alnum:]" | head -c32768 > temp.txt
data=$(cat ./temp.txt)

for testdir in "$@"; do
    echo "create directory '$testdir'"
    mkdir -p $testdir
    for i in {1..3}; do
        counter=$(printf %02d $i)
        testfile=$testdir/test_${testdir##*/}_$counter.txt
        echo "create file '$testfile'"
        echo "$data" > $testfile
    done
done

このスクリプトを使用して3000ファイル(各フォルダに3つのファイルがあります)を作成しようとすると、システムは約19秒かかります。

時間 generateUserData.sh テスト {0..1000}

create directory 'TEST999'
create file 'TEST999/test_TEST999_01.txt'
create file 'TEST999/test_TEST999_02.txt'
create file 'TEST999/test_TEST999_03.txt'
create directory 'TEST1000'
create file 'TEST1000/test_TEST1000_01.txt'
create file 'TEST1000/test_TEST1000_02.txt'
create file 'TEST1000/test_TEST1000_03.txt'

real    0m19.333s
user    0m14.791s
sys     0m4.784s

echo私はこれが遅い部分かもしれないことを知っています。できるだけ早く彼を終わらせる方法についてのアイデアはありますか?

ベストアンサー1

遅いプロセスでは、プロセスを分岐して外部コマンドを実行することをお勧めします。mkdir

counter=$(printf %02d $i)

また、bashでプロセスをフォークします。次のように書くことでこれを防ぐことができます。

printf -v counter %02d "$i"

または:

printf -v testfile %s/%s_%02d.txt "$testdir" "${testdir##*/}" "$i"

mkdirファイルごとに1つずつ実行するのではなく、1回の呼び出しですべてのディレクトリを作成します(mkdir -p -- "$@";忘れないでください)。--mkdir

次のいずれかに一時ファイルは必要ありません。

data=$(< /dev/urandom tr -dc "\t\n [:alnum:]" | head -c32768; echo .)
data=${data%.}

.コマンド置換が削除されるため、32768バイトを含めるようにするには追加が$data必要です。みんな末尾の改行文字。また、誰も追加されないechoことに注意してください。-n任意のデータの場合は、printfとにかく代わりに使用する必要があります。echo

また、head -c 32768文字ではなく32768バイトを提供するため、文字が途中で切り取られる可能性があります。

printf %s "$data" > "$file"

おすすめ記事