如何在第一列中找到重复项,然后删除整行?

Sua*_*ıcı 4 command-line duplicate text-processing uniq

我有一个 xlsx 文件(110725x9 矩阵),我保存为文本类型(制表符分隔),因为我不知道 Unix 是否对 xlsx 文件有帮助。重复的行总是逐行连续的。

例如,假设文本文件如下。你会看到 3,4-th、7,8-th 和 17,18-th 行是相同的。我想删除不总是较低的上部重复行。

2009,37214611872    2009    135 20  17,1    17,4    19,2    21,8    24,1
2009,37237442922    2009    135 22  16,5    14,5    12,6    11,2    10,5
2009,37260273973    2009    136 0   7,7     7,2     7,1     7,3     7,5
2009,37260273973    2009    136 0   7,7     7,2     7,0     7,2    7,4
2009,37488584475    2009    136 20  14,6    15,1    16,4    18,3    20,1
2009,37511415525    2009    136 22  15,9    14,6    12,8    10,9    9,4
2009,37534246575    2009    137 0   8,2     6,9     6,2     6,2     6,4
2009,37534246575    2009    137 0   8,1     6,8     6,1     6,0     6,3
2009,37557077626    2009    137 2   6,8     6,7     6,5     6,3     6,2
2009,37579908676    2009    137 4   5,8     5,6     5,4     5,4     5,7
2009,37602739726    2009    137 6   6,3     6,1     5,9     5,8     5,8
2009,37625570776    2009    137 8   4,5     5,2     6,0     6,6     7,2
2009,37648401826    2009    137 10  9,6     9,0     8,4     8,4     9,1
2009,37671232877    2009    137 12  11,4    11,7    12,4    13,4    14,4
2009,37694063927    2009    137 14  12,4    13,1    14,2    15,4    16,7
2009,37785388128    2009    137 22  15,5    14,0    12,2    10,3    8,7
2009,37808219178    2009    138 0   6,3     5,8     5,5     5,5     5,8
2009,37808219178    2009    138 0   6,2     5,7     5, 4    5,4     5,7
Run Code Online (Sandbox Code Playgroud)

所以输出应该是这样的:

2009,37214611872    2009    135 20  17,1    17,4    19,2    21,8    24,1
2009,37237442922    2009    135 22  16,5    14,5    12,6    11,2    10,5
2009,37260273973    2009    136 0   7,7     7,2     7,0     7,2    7,4
2009,37488584475    2009    136 20  14,6    15,1    16,4    18,3    20,1
2009,37511415525    2009    136 22  15,9    14,6    12,8    10,9    9,4
2009,37534246575    2009    137 0   8,1     6,8     6,1     6,0     6,3
2009,37557077626    2009    137 2   6,8     6,7     6,5     6,3     6,2
2009,37579908676    2009    137 4   5,8     5,6     5,4     5,4     5,7
2009,37602739726    2009    137 6   6,3     6,1     5,9     5,8     5,8
2009,37625570776    2009    137 8   4,5     5,2     6,0     6,6     7,2
2009,37648401826    2009    137 10  9,6     9,0     8,4     8,4     9,1
2009,37671232877    2009    137 12  11,4    11,7    12,4    13,4    14,4
2009,37694063927    2009    137 14  12,4    13,1    14,2    15,4    16,7
2009,37785388128    2009    137 22  15,5    14,0    12,2    10,3    8,7
2009,37808219178    2009    138 0   6,2     5,7     5, 4    5,4     5,7
Run Code Online (Sandbox Code Playgroud)

我怎么能在不排序的情况下做到这一点?

mur*_*uru 8

要基于单个列删除重复项,您可以使用awk

awk '!seen[$1]++' input-file > output-file
Run Code Online (Sandbox Code Playgroud)

您可以在这篇 Unix & Linux post 中看到对此的解释。

删除旧行更复杂。鉴于重复总是在一起,你可以这样做:

awk 'prev && ($1 != prev) {print seen[prev]} {seen[$1] = $0; prev = $1} END {print seen[$1]}' input-file > output-file
Run Code Online (Sandbox Code Playgroud)

这里,在中间块中,{seen[$1] = $0}将当前行 ( $0)保存到seen以第一个字段 ( $1) 作为索引的数组中,然后将第一个字段保存在prev变量中。这prev在处理下一行时在第一个块中使用。

然后,在第一个块中,我们检查是否prev已设置(仅对第二行以后为真)并且不等于当前的第一个字段(这里prev是在处理前一行时设置的)。如果不是,我们已经移动了重复项并且可以打印前一行。在 处END,我们对最后一行再次执行此操作。

  • 如果删除下部重复项更容易,删除上部重复项的可能“解决方案”是`tac | awk [删除较低的重复项] | tac` :-) (2认同)