![删除给定列中的重复字段(ID 检查后)](https://linux22.com/image/54461/%E5%88%A0%E9%99%A4%E7%BB%99%E5%AE%9A%E5%88%97%E4%B8%AD%E7%9A%84%E9%87%8D%E5%A4%8D%E5%AD%97%E6%AE%B5%EF%BC%88ID%20%E6%A3%80%E6%9F%A5%E5%90%8E%EF%BC%89.png)
我想从给定列(示例中的 $2)中删除重复字段(逗号分隔),但前提是 ID 列(示例中的 $1)相同。
输入:
A 1,2,3,4
A 8,9,10,11
A 2,3,4,11,12
B 4,5,6,7
B 6,8,9,10
预期输出:
A 1,2,3,4
A 8,9,10,11
A 12
B 4,5,6,7
B 8,9,10
答案1
{
split($2, elements, ",")
out = ""
for (i in elements) {
el = elements[i]
key = $1 " " el
if (!(key in used)) {
out = out el ","
}
used[key] = 1
}
sub(/,$/, "", out)
$2 = out
}
1
对于每一行,我们用逗号分隔第二列并将这些位保存到数组中elements
。然后,我们使用循环构建该列的新值,检查我们之前是否见过该值。
我们保留在(关联)数组中已经看到的一组值used
。我们构造一个字符串key
,其中包含第一列的值和我们当前正在查看的第二列的值。如果key
是 in used
,则我们之前已经见过此 ID,因此不应将其放入输出中;否则,它是新的,我们将值连接到out
。为了不再使用它,我们将key
(类似于“ A 3
”)存储到我们看到的元素集中。
最后,我们将构建的列表放回第二列。这本质上是您在任何其他语言中采用的方法。
将上面的代码放入一个文件中并使用awk -f
或单引号将其全部作为命令行上的参数运行。
答案2
perl -lpe 's/(\S+)\s+\K\S+/join ",", grep {!$seen{$1}->{$_}++} split ",", $&/e'