This:
echo " " | tr ' ' 'n' | sed "s|.*|$RANDOM|"
或者这个:
echo " " | tr ' ' 'n' | sed "s|.*|$(echo $RANDOM)|"
将打印一个包含 5 个数字的列表(空格替换为换行符,sed 将每行替换为 $RANDOM(,这 5 个数字将全部相同:
$ echo " " | tr ' ' 'n' | sed "s|.*|$(echo $RANDOM)|"
21590
21590
21590
21590
21590
这是因为将$RANDOM替换为随机值只发生一次。
什么是最简单和最短的方法,最好只使用 sed,为每行实际打印不同的随机数。 即提供一些"辅助输入流",该输入流对于 sed 处理的每一行都不同?
我可以用 xargs 做到这一点,但我想知道是否有办法只用 sed 来做到这一点。
不,仅使用 sed 是不可能的,因为 sed 无法生成随机数。在您发布的示例中甚至不是 sed 在这样做,而是在调用 sed 之前生成随机数的 shell。所有sed看到的都是"s|.*|21590|"
.
如果你想在任何UNIX盒子上的任何shell中使用标准工具来做到这一点,那么你可以用任何awk来做到这一点:
$ echo " " | tr ' ' 'n' | awk '{sub(/.*/,rand())}1'
0.924046
0.593909
0.306394
0.578941
0.740133
有关rand()
的更多信息,请参阅 https://www.gnu.org/software/gawk/manual/gawk.html#Numeric-Functions,如果您有兴趣寻求awk解决方案,我可以提供C&V。
在下面解决您的评论的一种方式:
$ seq 5 | awk -v seed="$RANDOM" 'BEGIN{srand(seed)} {print rand()}'
0.0873814
0.536876
0.535788
0.881146
0.354652
取决于你的sed
版本,但是 -
$: cat x
a
b
c
d
e
$: sed 's/.*/printf "%05dn" $RANDOM/e' x
30181
30514
24742
28555
26267
e
意味着e
,并生成一个子壳,所以要警惕成本。
补遗
您可以格式化输出。 printf "%07.7sn" $(($RANDOM%10000))$(($RANDOM%10000))
将始终使用前导零焊盘打印 7 位数字,并改进默认范围的约束,这使得 10000 个以 1 开头的数字、以 2 开头的 10000 个数字和 2,767 个以 3 开头的数字,总共 32,767 个数字(除了正常的 0-9999 范围内的数字 - 不是理想的分布。您也可以只使用awk
获得更好的随机数。
对你有用(GNU sed 和 Bash(:
seq 5 | sed 's/.*/echo $RANDOM/e'
这会将数字 1 到 5 替换为 echo $RANDOM
并计算每一行。
注意:GNU SED使用/bin/sh
可以通过符号链接定向到/bin/dash
在这种情况下,将找不到环境变量$RANDOM
。有多种解决方案可以解决这个问题,但可能最简单(尽管可能很危险(是:
sudo ln -sf /bin/bash /bin/sh
# run sed
sudo ln -sf /bin/dash /bin/sh
另一个替代:
shuf -i 1-100000 -n 5
问题:
最简单和最短的方法是什么,最好只使用 sed,为每行实际打印不同的随机数?
答:
echo " " | tr ' ' 'n' | perl -pe 's|.*|int(rand(89999))+10000|e'
或者简单地:
perl -e 'printf "%05sn",int(rand(100000)) for (1..5)'
解释:
我不明白为什么一个人不使用Perl,或任何可能更适合这项工作的工具。在OP中,没有暗示有理由坚持sed
,相反,这只是一种偏好。
我想知道为什么要进行替换以打印五个随机数。没有给出关于大局的细节,但这确实让我很好奇。
如果你想要相同的随机数
random=$(cat /dev/urandom | tr -cd '0-9' | head -c 5)
echo -e "$randomn$randomn$randomn$randomn$random"
如果您每次想要不同的数字。这里的问题是很难设置你得到多少个字符
echo -e "$RANDOMn$RANDOMn$RANDOMn$RANDOMn$RANDOM"
或者更合乎逻辑的是相同的数字
random=$(cat /dev/urandom | tr -cd '0-5' | head -c 8)
x=0
while (($x < 5)); do echo "$random";((x++));done
或者更合乎逻辑地用于不同的数字
x=0
while (($x < 5)); do random=$(cat /dev/urandom | tr -cd '0-5' | head -c 8); echo "$random";((x++));done
我在下面找到了解决方案:
$ seq 5 | sed "s/.*/date +%N | grep -o '[0-9][0-9][0-9][0-9][0-9]$'/e"
16794
76358
17143
60690
70506
它使用纳秒计时器的最后 5 个数字来生成一个合理的随机熵质量随机数。