我需要帮助来改进我的工作代码,以便根据指定列的相同值组合多行。 以下是一个示例数据:
c-i1_pos-at1-v2 162a AT1G01040.1 2 3422-3443 3433 1
c-i1_pos-at1-v2 162b AT1G01040.1 2 3422-3443 3433 1
pare-i_226-v2-wt 162a AT1G01040.1 2 3422-3443 3433 0
pare-i_226-v2-wt 162b AT1G01040.1 2 3422-3443 3433 0
xrn4-pare-i_ath-227-v2-wt 827 AT1G02860.1 1 258-278 269 1
i2_lib2-v2 156a AT1G03730.1 4 242-260 252 3
i2_lib2-v2 156b AT1G03730.1 4 242-260 252 3
i2_lib2-v2 156c AT1G03730.1 4 242-260 252 3
i2_lib2-v2 156d AT1G03730.1 4 242-260 252 3
i2_lib2-v2 156e AT1G03730.1 4 242-260 252 3
基本上,如果$ 3,$ 5列中的值相同,我想合并$ 2,$ 6(或更多)列的行,其余列的唯一值合并如下:
AT1G01040.1 3422-3443 3433 162a,162b
AT1G02860.1 258-278 269 827
AT1G03730.1 242-260 252 156a,156b,156c,156d,156e
目前我正在尝试根据答案here分多步执行此操作。
awk 'BEGIN{FS=OFS="\t"} {c=$2 FS $3 FS $5; if (c in a) a[c]=a[c]","$6; else a[c]=$6}END{for (k in a) print k,a[k]}'|awk '{p=$1 FS $2 FS $4; if (p in l) l[p]=l[p]","$3;else l[p]=$3}END{for (m in l) print m,l[m]}' <input.txt
给出了:
AT1G01040.1 3422-3443 3433,3433 162a,162b
AT1G02860.1 258-278 269 827
AT1G03730.1 242-260 252 156a,156b,156c,156d,156e
我认为我应该将剩下的列中的值作为数组放在一步得到我想要的输出,但我正在努力找出正确的上下文。
答案 0 :(得分:2)
像
这样的东西awk '{if ( $3 in a ) a[$3] = a[$3]","$2; else a[$3] = $3" "$5" "$6" "$2} END{for (i in a) print a[i]}' inputFile
将产生输出
AT1G03730.1 242-260 252 156a,156b,156c,156d,156e
AT1G02860.1 258-278 269 827
AT1G01040.1 3422-3443 3433 162a,162b,162a,162b
<强>解释强>
a[$3] = $3" "$5" "$6" "$2
创建一个由第三个字段a
索引的数组$3
,else
部分确保在第一次遇到该行时创建该数组。
if ( $3 in a ) a[$3] = a[$3]","$2
如果第三个字段$3
已存在于数组中,则将字段2 $2
附加到数组
END{for (i in a) print a[i]}
END
阻止在输入结束时被删除。打印整个数组,给出输出
修改强>
更简单的版本是
awk '{( $3 in a ) ? a[$3] = a[$3]","$2 : a[$3] = $3" "$5" "$6" "$2} END{for (i in a) print a[i]}' inputFile
谢谢Jotne的建议。