如何仅在特定条件(上下文)下使用来自另一个字段的值更新列中字段的值?
How to update the value of a field in a column with value from another field only in specific conditions (context)?
我有一个文件,当该列的第 5 个字段中有上下文(管道即 |)时,我想在该文件中更新特定列(比如 1 和 2)的第一个字段中的值。
我可以使用 python 但是拆分行、替换值并连接它们将是一个很长的脚本。我正在寻找使用 awk(pefereable)的解决方案,其他人也很好,但很短。我也想将其嵌入 python 脚本中。
下面是我数据中的两列,列中的字段用 (:) 分隔。
0/1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0/1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0/1:145,34:179:99:0|1:5398_A_G:973,0,6088
因此,当该列中的第 5 个字段具有“|”时我们用第 5 个字段值更新第一个字段。
预期结果:
0|1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0|1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0|1:145,34:179:99:0|1:5398_A_G:973,0,6088
-实际上,有很多专栏。而且,假设这种列出现在第 5 个 python 索引位置之后,我想在第 5 列之后的每个列字段中进行替换,我该如何解决这个问题。
谢谢,
谢谢,
$ awk '{ for (i=1;i<=NF;i++) { split($i,f,/:/); if (f[5]~/\|/) sub(/^[^:]+/,f[5],$i) } }1' file
0|1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0|1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0|1:145,34:179:99:0|1:5398_A_G:973,0,6088
唯一需要注意的是,第 5 个子字段不能包含 &
,因为那将是 sub() 中的反向引用元字符。
如果要从第 5 列开始替换,请在循环初始化部分将 i=1 更改为 i=5。
分成几行:
$ awk '{
for (i=1;i<=NF;i++) {
split($i,f,/:/)
if (f[5]~/\|/)
sub(/^[^:]+/,f[5],$i)
}
}1' file
我有一个文件,当该列的第 5 个字段中有上下文(管道即 |)时,我想在该文件中更新特定列(比如 1 和 2)的第一个字段中的值。
我可以使用 python 但是拆分行、替换值并连接它们将是一个很长的脚本。我正在寻找使用 awk(pefereable)的解决方案,其他人也很好,但很短。我也想将其嵌入 python 脚本中。
下面是我数据中的两列,列中的字段用 (:) 分隔。
0/1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0/1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0/1:145,34:179:99:0|1:5398_A_G:973,0,6088
因此,当该列中的第 5 个字段具有“|”时我们用第 5 个字段值更新第一个字段。
预期结果:
0|1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0|1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0|1:145,34:179:99:0|1:5398_A_G:973,0,6088
-实际上,有很多专栏。而且,假设这种列出现在第 5 个 python 索引位置之后,我想在第 5 列之后的每个列字段中进行替换,我该如何解决这个问题。
谢谢,
谢谢,
$ awk '{ for (i=1;i<=NF;i++) { split($i,f,/:/); if (f[5]~/\|/) sub(/^[^:]+/,f[5],$i) } }1' file
0|1:42,19:61:99:0|1:5185_T_TTCTATC:560,0,1648 0|1:38,34:72:99:0|1:5185_T_TTCTATC:1145,0,1311
0/0:124,0,0:124:99:0,120,1800,120,1800,1800 0/0:165,0,0:165:99:0,120,1800,120,1800,1800
0/0:152,0:152:99:.:.:0,120,1800 0|1:145,34:179:99:0|1:5398_A_G:973,0,6088
唯一需要注意的是,第 5 个子字段不能包含 &
,因为那将是 sub() 中的反向引用元字符。
如果要从第 5 列开始替换,请在循环初始化部分将 i=1 更改为 i=5。
分成几行:
$ awk '{
for (i=1;i<=NF;i++) {
split($i,f,/:/)
if (f[5]~/\|/)
sub(/^[^:]+/,f[5],$i)
}
}1' file