分配变量并在 gsub 中使用
assigning variables and using in gsub
我有一个包含 12 个字段的文件
LINE1 CC CC CC CG CG CG CG BRE CC GG CG
LINE2 GG AA AA AA AA AA AA BRH AA GG AG
LINE3 HH HH HL LL LL LL LL BGH LL HH HL
我想分配三个变量 X=
、y=
、z=
。然后我想用另一个值替换字段 2 - 8,具体取决于它们匹配我的哪些变量(当将 x sub 与 1 匹配时,当将 y sub 与 2 匹配时,以及当将 z sub 与 3 匹配时)。注意:变量改变每一行。
文件应该是这样的
LINE1 1 1 1 3 3 3 3 BRE CC GG CG
LINE2 2 1 1 1 1 1 1 BRH AA GG AG
LINE3 2 2 3 1 1 1 1 BGH LL HH HL
这是我试过的
awk '{x="; y=""; z="; gsub(/x/, "1") && gsub(/y/, "2") && gsub(/z/, "3"); print [=12=]}'
我相信这会满足您的要求:
$ awk '{for (i=2;i<=8;i++) $i=($i==)?1:($i==)?2:($i==)?3:$i; print}' file
LINE1 1 1 1 3 3 3 3 BRE CC GG CG
LINE2 2 1 1 1 1 1 1 BRH AA GG AG
LINE3 2 2 3 1 1 1 1 BGH LL HH HL
工作原理
我们只想对字段 2 到 8 进行替换。因此,我们依次循环它们:
for (i=2;i<=8;i++) $i=($i==)?1:($i==)?2:($i==)?3:$i
此命令遍历每个字段 i
,从 2 到 8,一次一个。对于每个字段,如果 $i==
则 $i
替换为 1,如果 $i==
则替换为 2,如果 $i==
则替换为 3,否则保持不变为 $i
。
这个逻辑是用三个 'ternary' 语句实现的。在 awk
中,三元语句如下所示:
($i==)?3:$i
第一部分,($i==)
,是一个条件。如果为真,那么语句returns就是?
之后的值。如果它是 false,那么它 returns 是 :
之后的值。因此,如果$i
等于</code>,则此语句returns的值为<code>3
,否则returns的值为$i
。上面的逻辑将三个这样的语句链接在一起。
print
打印新行。
awk '{for(i=10;i<=12;++i){for(x=2;x<=8;++x){if($i==$x){$x=i-9}}};print}' file
编辑:这是一个使用 sub 函数的更聪明的解决方案
awk '{for(i=10;i<=12;++i){for(x=2;x<=8;++x){if($i==$x){sub($x,i-9,$x)}}};print}' file
我有一个包含 12 个字段的文件
LINE1 CC CC CC CG CG CG CG BRE CC GG CG
LINE2 GG AA AA AA AA AA AA BRH AA GG AG
LINE3 HH HH HL LL LL LL LL BGH LL HH HL
我想分配三个变量 X=
、y=
、z=
。然后我想用另一个值替换字段 2 - 8,具体取决于它们匹配我的哪些变量(当将 x sub 与 1 匹配时,当将 y sub 与 2 匹配时,以及当将 z sub 与 3 匹配时)。注意:变量改变每一行。
文件应该是这样的
LINE1 1 1 1 3 3 3 3 BRE CC GG CG
LINE2 2 1 1 1 1 1 1 BRH AA GG AG
LINE3 2 2 3 1 1 1 1 BGH LL HH HL
这是我试过的
awk '{x="; y=""; z="; gsub(/x/, "1") && gsub(/y/, "2") && gsub(/z/, "3"); print [=12=]}'
我相信这会满足您的要求:
$ awk '{for (i=2;i<=8;i++) $i=($i==)?1:($i==)?2:($i==)?3:$i; print}' file
LINE1 1 1 1 3 3 3 3 BRE CC GG CG
LINE2 2 1 1 1 1 1 1 BRH AA GG AG
LINE3 2 2 3 1 1 1 1 BGH LL HH HL
工作原理
我们只想对字段 2 到 8 进行替换。因此,我们依次循环它们:
for (i=2;i<=8;i++) $i=($i==)?1:($i==)?2:($i==)?3:$i
此命令遍历每个字段
i
,从 2 到 8,一次一个。对于每个字段,如果$i==
则$i
替换为 1,如果$i==
则替换为 2,如果$i==
则替换为 3,否则保持不变为$i
。这个逻辑是用三个 'ternary' 语句实现的。在
awk
中,三元语句如下所示:($i==)?3:$i
第一部分,
($i==)
,是一个条件。如果为真,那么语句returns就是?
之后的值。如果它是 false,那么它 returns 是:
之后的值。因此,如果$i
等于</code>,则此语句returns的值为<code>3
,否则returns的值为$i
。上面的逻辑将三个这样的语句链接在一起。print
打印新行。
awk '{for(i=10;i<=12;++i){for(x=2;x<=8;++x){if($i==$x){$x=i-9}}};print}' file
编辑:这是一个使用 sub 函数的更聪明的解决方案
awk '{for(i=10;i<=12;++i){for(x=2;x<=8;++x){if($i==$x){sub($x,i-9,$x)}}};print}' file