我想为一些实验生成一些大文件。
这是我的脚本。它创建一个文件,然后将其读取到一个变量中,然后尝试将其写入文件中循环中定义的多次:
#! /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 TEST{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
可能是这里的缓慢部分。任何想法我怎样才能让他尽可能快?
更慢的是分叉进程和执行外部命令,例如
mkdir
还在 bash 中分叉了一个进程。这可以通过将其编写为来避免:
或者:
mkdir
使用一次调用 (mkdir -p -- "$@"
; 不要忘记)创建所有目录,而不是每个文件--
运行一个。mkdir
也不需要临时文件:
如果您想保证包含 32768 个字节,则添加
.
是必要的,因为命令替换会删除所有尾随换行符。另请注意,不加一回。应该使用而不是无论如何用于任意数据:$data
echo
-n
printf
echo
还要注意
head -c 32768
给你 32768 字节,而不是字符,所以可以在中间剪切字符。接受Stéphane Chazelas在他们的精彩回答中所说的一些内容,并进行一些调整。
dd
- 获取确切字节数的替代方法(尽管这种情况只发生一次,但无论哪种方式都不会产生太大影响)echo
在我结束时增加了大约 3 秒,计数为 1000proc
变量)——四处寻找适合您系统的最佳值例如
注意 - 假设您关于填充变量的原始问题是XY 问题的一个实例......如果这是一个硬性要求,那么我的回答在书面上是无效的。
这种改变应该做到这一点:
第二个
dd
是确保我们只获得生成的数据,没有它,介于两者之间$( )
,<<<
我们似乎从某个地方找到了一个额外的字节(隐含的换行符?)。很高兴对此进行更正。我承认看起来有点麻烦,如果随机数据的大小是任意的或不重要的,你可以简化这个我敢肯定