如何将随机字符串插入 sed 's//'替换每行操作的字符串?



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 个数字来生成一个合理的随机熵质量随机数。

最新更新