基于相同列在行中组合多个列值

时间:2014-10-30 09:14:28

标签: bash awk

我需要帮助来改进我的工作代码,以便根据指定列的相同值组合多行。 以下是一个示例数据:

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

我认为我应该将剩下​​的列中的值作为数组放在一步得到我想要的输出,但我正在努力找出正确的上下文。

1 个答案:

答案 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索引的数组$3else部分确保在第一次遇到该行时创建该数组。

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的建议。