通过 bash 快速生成文件内容

Fast file content generating via bash

任务是在 bash 中编写脚本,生成从 1 到某个数字的数字,同时文件大小小于 5 Mb。我已经写了剧本,但它太慢了。我怎样才能将它的速度提高到 2 秒?

#!/bin/bash
if ! [ -f task3.txt ]
then
        touch task3.txt
fi
limit=5242880
size=`wc -c < task3.txt`
i=1
while [ $size -le $limit ]
do
        echo "$i " >> task3.txt
        i=$((i+1))
        size=`wc -c < task3.txt`
done

不用 运行 文件系统,每次都重新计算每个字节来计算你写了多少,你自己保持计数。正如目前所写,您可以使用

size=$((size + ${#i} + 2))

在循环内。这里 ${#i}$i 的长度,每个循环多了两个,因为除了它之外你还回显了 space 和一个换行符。如果 space 是错字,正如我怀疑的那样,那么你的循环可能是

while [ $size -le $limit ]
do
    echo "$i" >> task3.txt     # cut space
    i=$((i+1))
    size=$((size + ${#i} + 1)) # only +1 here.
done

此外,为了避免一直打开和关闭管道,你可以这样写

while [ $size -le $limit ]
do
    echo "$i"                  # cut space
    i=$((i+1))
    size=$((size + ${#i} + 1)) # only +1 here.
done >> task3.txt

这并没有像删除 wc -c 那样减少 运行 时间,但它仍然是 ~50%(非常值得)。

速度极快的附录:

另一种比手动循环快得多的方法是滥用 seq,如下所示:

left=$((limit - size))      # bytes left to write

seq 1 $left | head -c $left >> task3.txt

这滥用了 head -c $left$left 字节后停止读取的事实,此时 seq 的标准输出关闭并且 seq 也停止写入,并且 seq 1 $left 将打印超过 $left 字节的输出。需要注意的是,它写入的不是 n 个数字,而是 n 个字节,因此输出中的最后一个数字可能会被截断。从空文件开始时不是在这种特殊情况下,而是偶然。

感谢@gniourf_gniourf 提出了大部分内容。