Text-Processing
合併特定列中的多行
我有一個這樣的文件:
xxx ax1 bx1 xxx ax2 bx2 cx2 xxx ax3 bx3 yyy ay1 cy1 zzz az1 cz1 zzz az1 bz2 ...
我想要這樣的輸出:
xxx ax1,ax2,ax3 bx1,bx2,bx3 cx2 yyy ay1 cy1 zzz az1 bz2 cz1 ...
我嘗試使用 awk
awk -F'\t' -v OFS='\t' '{x=$1;$1="";a[x]=a[x]$0}END{for(x in a)print x,a[x]}' file
。但是這個命令忽略了它們所屬的列,輸出不是我想要的。
awk ' BEGIN{ FS=OFS="\t" } { for(i=2; i<=NF;i++) if (!seen[$1, $i, i]++) grp[$1, i]=(grp[$1, i]==""?"":grp[$1, i] ($i!=""?",":"")) $i else grp[$1, i]= grp[$1, i] } END{ for(x in grp) { split(x, tmp, SUBSEP); join[tmp[1]]=(join[tmp[1]]==""?"":join[tmp[1]] OFS) grp[x] } for (x in join) print x, join[x] }' infile
輸出:
yyy ay1 cy1 xxx ax1,ax2,ax3 bx1,bx2,bx3 cx2 zzz az1 bz2 cz1
將欄位括在括號內以檢查其位置是否正確:
awk ' BEGIN{ FS=OFS="\t" } { for(i=2; i<=NF;i++) if (!seen[$1, $i, i]++) grp[$1, i]=(grp[$1, i]==""?"":grp[$1, i] ($i!=""?",":"")) $i else grp[$1, i]= grp[$1, i] } END{ for(x in grp) { split(x, tmp, SUBSEP); join[tmp[1]]=(join[tmp[1]]==""?"":join[tmp[1]] OFS) "["grp[x]"]" } for (x in join) print x, join[x] }' infile
輸出:
yyy [ay1] [] [cy1] xxx [ax1,ax2,ax3] [bx1,bx2,bx3] [cx2] zzz [az1] [bz2] [cz1]
筆記:
- 無論您的輸入是否已排序,此答案都將起作用。
- 這個答案將在輸出時打亂記錄。
- 該程式碼
!seen[$1, $i, i]++
用於區分列中每個 Id 的條目。如果要刪除所有列中的重複條目而不考慮 ID,請將其更改為!seen[$1, $i]++
);例如:
$ cat infile xxx ax1 ax1 xxx ax1 bx2 ax3 xxx ax3 bx2 yyy ay1 ay1 cy3 zzz az1 bz3 cz1 zzz az1 bz2 bz3
輸出(當
!seen[$1, $i, i]++
);重複的條目僅在屬於該 Id 的每一列中被刪除:yyy [ay1] [ay1] [cy3] xxx [ax1,ax3] [ax1,bx2] [ax3] zzz [az1] [bz3,bz2] [cz1,bz3]
輸出(當
seen[$1, $i]++
);無論該條目的列位置如何,都會刪除所有重複的條目:yyy [ay1] [] [cy3] xxx [ax1] [bx2] [ax3] zzz [az1] [bz3,bz2] [cz1]