【问题标题】:How to generate 10 million random strings in bash如何在 bash 中生成 1000 万个随机字符串
【发布时间】:2017-11-26 22:57:25
【问题描述】:

我需要为排序算法制作一个大的测试文件。为此,我需要生成 1000 万个随机字符串。我怎么做?我尝试在 /dev/urandom 上使用 cat 但它会持续几分钟,当我查看文件时,只有大约 8 页的字符串。如何在 bash 中生成 1000 万个字符串?字符串长度应为 10 个字符。

【问题讨论】:

  • (1) /dev/null?那将如何运作? (2) bash 不是适合这项工作的工具。我建议使用其他东西。 (3) 什么样的字符串?多长?您当然可以将base64 编码的输入作为/dev/urandom,然后将其拆分成块。你需要多大的块?单个字符算作“字符串”吗?细节很重要。
  • 我想写urandom,这就是我正在使用的。对不起。
  • 统一长度是否可以对您的排序代码进行最佳测试?你真的需要变长字符串吗?或者这只是前进道路上的第一步?
  • 所有唯一的?字符串的格式?单独的数字还是十六进制?

标签: string bash random generator


【解决方案1】:

使用 openssl:

#!/bin/bash

openssl rand -hex $(( 100000000 * 4 )) | \
while IFS= read -rn8 -d '' r; do
    echo "$r"
done

【讨论】:

  • 分叉出一个新程序每一次迭代?!这太慢了,而且完全没有必要(当你可以只调用一次 openssl rand 吐出你需要的所有字节,然后将其拆分为字符串)。
  • 谢谢,查尔斯。我已经更新了我的答案。如果 openssl 可以选择禁止尾随换行符,那就太好了!
  • 确实好多了。
【解决方案2】:

这不会保证唯一性,但会在一个文件中为您提供 1000 万个随机行。不算太快,但在我的机器上运行不到 30 秒:

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 10000000 > file

【讨论】:

  • 丢弃不是字母数字的字符非常昂贵——您使用的来自/dev/urandom 的字节比您需要的要多。
  • Charles Duffy 是对的,您可以将前两个命令替换为 base64 -w0 /dev/urandom。这在我的机器上大约 7 秒内完成。
  • 当然,cat is useless -- tr 很讨厌,因为它不接受文件名参数,但 tr -dc 'a-zA-Z0-9' </dev/urandom 可以很好地解决这个问题
【解决方案3】:

更新,如果你有来自 GNU coreutilsshuf,你可以使用:

shuf -i 1-10000000 > file

在我的电脑上需要 2 秒。 (感谢rici!)


您可以使用awk 生成序列号并使用shuf 将它们打乱:

awk 'BEGIN{for(i=1;i<10000001;i++){print i}}' | shuf > big-file.txt

这在我的电脑上大约需要 5 秒

【讨论】:

  • 这比 awk 中的相同循环要慢得多,尤其是如果我们不关心重复(因此不需要花费shuf)。
  • 你说我应该使用awk 'BEGIN{for(i=1;i&lt;n;i++){print i}}' ... 而不是bash循环?
  • 如果这是 Gnu shuf,请使用 -i 标志。
【解决方案4】:

如果他们不需要是 uniq,你可以这样做:

$ awk -v n=10000000 'BEGIN{for (i=1; i<=n; i++) printf "%010d\n", int(rand()*n)}' >big_file

在我的 iMac 上运行大约需要 3 秒。

【讨论】:

    【解决方案5】:

    不要生成它,下载它。例如,Nic funet fi 在其/dev 中有文件100Mrnd(大小为104857600)(就在下面的funet)。 10M 行,每行 10 个字节为 100M,但使用 xxd 从 bin 转换为 hex(\x12 -> 12)我们只需要 50M 字节,所以:

    $ wget -S -O - ftp://funet/100Mrnd | head -c 50000000 | xxd -p | fold -w 10 > /dev/null
    $ head -5 file
    f961b3ef0e
    dc0b5e3b80
    513e7c37e1
    36d2e4c7b0
    0514e626e5
    

    (将 funet 替换为给定的域名和路径,将/dev/null 替换为您想要的文件名。)

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2017-02-14
      • 2019-02-23
      • 2020-03-05
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多