$ awk 'BEGIN{srand()} {for (i=1;i<=NF;i++) {if (substr($i,1,1)=="{") {split(substr($i,2,length($i)-2),a,"|"); j=1+int(rand()*length(a)); $i=a[j]}}; print}' math.txt
First: 172 + 1
Second: John had 12 apples and lost 3
工作原理
-
BEGIN{srand()}
这会初始化随机数生成器。
-
for (i=1;i<=NF;i++) {if (substr($i,1,1)=="{") {split(substr($i,2,length($i)-2),a,"|"); j=1+int(rand()*length(a)); $i=a[j]}
这会遍历每个字段。如果任何字段以{ 开头,则substr 用于删除字段的第一个和最后一个字符,其余部分以| 作为分隔符拆分为数组a。然后,选择数组a 中的随机索引j。最后,将字段替换为a[j]。
-
print
如上修改的那行被打印出来了。
与上面相同的代码,但重新格式化为多行,是:
awk 'BEGIN{srand()}
{
for (i=1;i<=NF;i++) {
if (substr($i,1,1)=="{") {
split(substr($i,2,length($i)-2),a,"|")
j=1+int(rand()*length(a))
$i=a[j]
}
}
print
}' math.txt
修正了空格问题
假设match.txt 现在看起来像:
$ cat math.txt
First: {736|172|201|109} {+|-|*|%|/} {21|62|9|1|0}
Second: John had {22|12|15} apples and lost {2|4|3}
Third: John had {22 22|12 12|15 15} apples and lost {2 2|4 4|3 3}
最后一行在{...} 中有空格。这改变了 awk 划分字段的方式。对于这种情况,我们可以使用:
$ awk -F'[{}]' 'BEGIN{srand()} {for (i=2;i<=NF;i+=2) {n=split($i,a,"|"); j=1+int(n*rand()); $i=a[j]}; print}' math.txt
First: 736 + 62
Second: John had 12 apples and lost 3
Third: John had 15 15 apples and lost 2 2
它是如何工作的:
-
-F'[{}]'
这告诉 awk 使用 } 或 { 作为字段分隔符。
-
BEGIN{srand()}
这会初始化随机数生成器
-
{for (i=2;i<=NF;i+=2) {n=split($i,a,"|"); j=1+int(n*rand()); $i=a[j]}
使用我们对字段分隔符的新定义,偶数字段是大括号内的字段。因此,我们在| 上拆分这些字段并随机选择一个并将字段分配给该字段:$i=a[j]。
-
print
如上修改该行,我们现在打印它。