问:如何将变量 $b 插入变量 $a 中真正随机的位置?
INPUT 变量内容示例:
$ echo $a
árvíztűrő tükörfúrógép
$ echo $b
ZZ
输出
$ ./somemagicscript.sh
árvíztűrő tüköZZrfúrógép
$ ./somemagicscript.sh
árvíztűrő tükörfúrZZógép
$ ./somemagicscript.sh
árvíztűrZZő tükörfúrógép
$ ./somemagicscript.sh
árvíztűrő tZZükörfúrógép
更新:当前的答案并不完美,因为在 OpenBSD 下有时会在插入的变量旁边放置一个“�”字符。 :\
也许比插入的变量紧邻多字节字符时更是如此。
答案1
sed "s/.\{$(($RANDOM%${#a}))\}/&$b/" <<< $a
在哪里:
$RANDOM
从 0 到$RAND_MAX
(通常0x7fff==32767)${#a}
目标字符串的长度$((...%...))
输出除法的余数.{n}
匹配输入字符串的前 n 个字符s/.../&$b/
替换模式匹配本身 +$b
答案2
其他答案给出了 sed 和 awk 的解决方案。如果您的 sed 和 awk 不支持多字节字符,那么您的 bash 仍然很有可能支持它们,因此这里有一个纯 bash 解决方案。
首先,我们选择一个介于 0 和字符串长度$a
(含)之间的随机数,以便$b
可以将字符串插入到 的任意两个字符之间$a
,或者在第一个字符之前,或者在最后一个字符之后。这存储在mid
.然后我们创建一个由(使用伪代码)组成的字符串a[0..mid-1] + b + a[mid..$]
(索引从 0 开始)。
$ cat ./multi
#!/bin/bash
a='árvíztűrő tükörfúrógép'
b='ZZ'
len=${#a}
echo "a is ${a} len is ${len}"
mid=$(((len + 1) * $RANDOM / 32767))
c="${a:0:$mid}${b}${a:$mid}"
echo "$c"
$ ./multi
a is árvíztűrő tükörfúrógép len is 22
árvíztűrő tükörfúrógéZZp
$ ./multi
a is árvíztűrő tükörfúrógép len is 22
árvízZZtűrő tükörfúrógép
$ ./multi
a is árvíztűrő tükörfúrógép len is 22
árvíztűrő tükörZZfúrógép
$ ./multi
a is árvíztűrő tükörfúrógép len is 22
ZZárvíztűrő tükörfúrógép
答案3
awk 中的尝试:
awk "{srand(); i=int(rand()*length(\$0)); print substr(\$0,0,i)\"${b}\"substr(\$0,i)}" <<< $a
答案4
在 Perl 中(适用于 shell 脚本):
perl -CSA -e '$_=shift; substr($_,int(rand(1+length)),0,shift); print' "$a" "$b"
请注意此处 1+length 的不同位置:在字符串的开头和每个字符之后。
ETA:是的,-CSA
指定命令行参数和标准输出(以及其他标准文件句柄)使用 UTF-8(多字节)。