如何像“dd”一样快地将重复的自由格式字符串写入文件?

Pet*_*r.O 6 bash dd shell-script

dd可以非常快地将重复\0 字节写入文件,但不能写入重复的任意字符串。
是否有一种bash-shell方法可以与“dd”(包括)一样快地编写重复的任意字符串\0

我在 6 个月的 Linux 中遇到的所有建议都是这样的printf "%${1}s" | sed -e "s/ /${2}/g",但这与 相比慢得令人痛苦dd,如下所示,并且sed在大约 384 MB(在我的盒子上)后崩溃——实际上这对于一行来说还不错——长度 :) -- 但它确实崩溃了!如果字符串包含换行符,
我想这不会成为问题sed

ddvs. printf+ 的速度比较sed

                            real        user        sys       
WRITE 384 MB: 'dd'          0m03.833s   0m00.004s   0m00.548s
WRITE 384 MB: 'printf+sed'  1m39.551s   1m34.754s   0m02.968s

# the two commands used   
dd if=/dev/zero bs=1024 count=$((1024*384))
printf "%$((1024*1024*384))s" |sed -e "s/ /x/g"
Run Code Online (Sandbox Code Playgroud)

我知道如何在bash-shell脚本中执行此操作,但没有必要重新发明轮子。:)

Mat*_*Mat 5

$ time perl -e \
    '$count=1024*1024; while ($count>0) { print "x" x 384; $count--; }' > out
real    0m1.284s
user    0m0.316s
sys 0m0.961s
$ ls -lh out
-rw-r--r-- 1 me group 384M Apr 16 19:47 out
Run Code Online (Sandbox Code Playgroud)

用您喜欢的任何内容替换"x" x 384(产生 384x秒的字符串)。

您可以通过在每个循环中使用更大的字符串并绕过正常的标准输出缓冲来进一步优化它。

$ perl -e \
   '$count=384; while ($count>0) {
      syswrite(STDOUT, "x" x (1024*1024),  1024*1024);
      $count--;
    }' > out
Run Code Online (Sandbox Code Playgroud)

在这种情况下,syswrite调用将一次向下传递 1M 到底层write系统调用,这变得非常好。(我得到了大约 0.940 秒的用户。)

提示:确保sync在每次测试之间调用以避免前一次运行的刷新干扰当前运行的 I/O。

作为参考,我这次得到:

$ time dd if=/dev/zero bs=1024 count=$((1024*384)) of=./out
393216+0 records in
393216+0 records out
402653184 bytes (403 MB) copied, 1.41404 s, 285 MB/s

real    0m1.480s
user    0m0.054s
sys 0m1.410s
Run Code Online (Sandbox Code Playgroud)