如何从CSV中删除重复行并从一列中连接值

时间:2017-11-29 22:41:49

标签: bash csv awk sed scripting

我想从CSV中删除重复的行并连接特定列的值(在本例中为column2)。

输入

ID column2 column3 column4, etc....
1  a       test3   test4
1  r       test3   test4
1  c       test3   test4
2  r       test3   test4
2  o       test3   test4
3  a       test3   test4
4  b       test3   test4
4  c       test3   test4
4  e       test3   test4

预期结果

ID column2 column3 column4, etc....
1  a|r|c   test3   test4
2  r|o     test3   test4
3  a       test3   test4
4  b|c|e   test3   test4

是否可以使用awk?

2 个答案:

答案 0 :(得分:1)

对于awk,对于变量列,适用于所有其他列可能更改的一般情况。

awk -v col=2 -v OFS="\t" '{
    temp=$col
    $col=""
    a[$0]=a[$0]? a[$0] "|" temp: temp
}
END {for (i in a) {
        split(i, b)
        for (j=1; j<=length(b); j++) {
            if (j==col) printf a[i] OFS
            printf b[j] OFS
        }
        printf ORS
    }
}' file |sort -n |column -t

这使用一个关联数组,其中不包含$col的行作为索引,并将$col的值附加到其中。

END,我们会在打印时将$col放回原位,将字段拆分为另一个数组。

输出的顺序未确定,您可以将其管道传输到sort以获取任何字段的任何排序类型。如果您需要,请column -t

答案 1 :(得分:0)

这可能对您有用(GNU sed&amp; column):

sed -r '1b;:a;$!N;s/^(\s*\S+\s)(\S+)\s*(\S+\s*\S+\s*)(.*)n\1(\S+)\s*\3/\1\2|\5 \3\4/;ta;P;D' file | column -t

除第一行之外的所有行上的模式匹配,然后使用反向引用和列命令格式化预期结果。

N.B。第一个字段被剥去了空白区域。