在bash中生成带有随机内容的大型csv

jvd*_*vdh 0 unix csv bash

我试图在bash中生成一个包含随机内容的大型csv.我的机器有6个核心和12G内存,但是我的脚本(见下文)只需要1个列的10k行,需要140秒.有没有办法优化这个脚本?

是否有更快的方法在其他语言中生成随机csv文件?

#!/bin/bash

csv="foo\tbar\tbaz"
start=$(date)
for i in `seq 1 $1`
  do rand=$(($i * $RANDOM))
  str0="$$"$i
  str1=$( echo "$str0" | md5sum )
  randstring1="${str1:2:8}"
  randstring2="${str1:0:2}"
  csv="$csv\n$randstring1\t$randstring2\t$rand"
done
end=$(date)
datediff=$(( $(date -d "$end" +%s) - $(date -d "$start" +%s)))
echo -e $csv > my_csv.csv
echo "script took $datediff seconds for $(wc -l my_csv.csv) lines"
Run Code Online (Sandbox Code Playgroud)

Win*_*ute 5

要相当精确地(格式化)替换此脚本,您可以使用

hexdump -v -e '5/1 "%02x""\n"' /dev/urandom |
  awk -v OFS='\t' '
    NR == 1 { print "foo", "bar", "baz" }
    { print substr($0, 1, 8), substr($0, 9, 2), int(NR * 32768 * rand()) }' |
  head -n "$1" > my_csv.csv
Run Code Online (Sandbox Code Playgroud)

这分为三个部分:

hexdump -v -e '5/1 "%02x""\n"' /dev/urandom
Run Code Online (Sandbox Code Playgroud)

/dev/urandom五个字节和格式的序列中提取,然后作为十六进制字符串,

awk -v OFS='\t' '
    NR == 1 { print "foo", "bar", "baz" }
    { print substr($0, 1, 8), substr($0, 9, 2), int(NR * 32768 * rand()) }'
Run Code Online (Sandbox Code Playgroud)

在添加相当于$(($i * $RANDOM))和标题行的字段时,适当地格式化行,以及

head -n "$1"
Run Code Online (Sandbox Code Playgroud)

采取这个的第一$1行.如果head退出,该管AWK关闭,awk退出,该管hexdump被关闭,hexdump退出,所以这使得整个事情最终在正确的时间.

在我的机器上(Haswell i5),运行它需要0.83秒,一百万行.