如何检查管道分隔文件中的每一行是否相同

如何检查管道分隔文件中的每一行是否相同

我有一个以竖线分隔的文件,可以包含数百万条记录。我想要做的是对文件进行排序,并删除其中是否有重复的行。

然后我需要检查前 32 列,看看第一行的内容是否与第二行匹配。如果是,则删除第二行,并再次检查第一行和第三行(由于删除了上一行,所以现在将成为第二行,因为它是相同的)。如果这也相同,则也删除第三行,并继续将第一行与文件中的后续行进行比较,直到我们得到不匹配的结果。例如: 输入文件:

a|a1|a2|a3|a4|...|a32|[email protected]
a|a1|a2|a3|a4|...|a32|[email protected]$1553:2015-02-14 
a|a1|a2|a3|a4|...|a32|[email protected]:2015-03-01 
a|a1|a2|a3|a4|...|a32|[email protected]$121:2015-01-31 
a|a1|a2|a3|a4|...|a32|[email protected]$293:2015-02-28 
b|b1|b2|b3|b4|...|b32|[email protected]$542:2013:05:24 
b|b1|b2|b3|b4|...|b32|[email protected]$542:2013:05:24 
b|b1|b2|b3|b4|...|b32|[email protected]:2013:05:24
b|b1|b2|b3|b4|...|b32|[email protected]$542:2013:05:24 
b|b1|b2|b3|b4|...|b32|[email protected]:2014:05:24 
c|c1|c2|c3|c4|...|c32|[email protected] 
c|c1|c2|c3|c4|...|c32|$200:2011:12:06 
c|c1|c2|c3|c4|...|c32|[email protected]$214:2001:01:31 

上例中有33个字段,用“...”表示连续性。因此,正如您所见,前 4 行是相同的(仅比较字段编号 32,该字段在示例中显示为“a32”)。所以我只需要保留第一个并删除其他的。同样,对于以 开头的列b,我们有 5 条相同的记录,因此再次删除最后 4 条并保留第一条。对于以 开头的记录c,我们只有 3 条记录,因此我们需要删除最后 2 条并保留第 1 条。因此,输出文件将是这样的:

所需的输出文件:

a|a1|a2|a3|a4|...|a32|[email protected]
b|b1|b2|b3|b4|...|b32|[email protected]$542:2013:05:24 
c|c1|c2|c3|c4|...|c32|[email protected] 

我正在考虑使用常规循环和 sed 命令来完成此操作,但它会显着减慢进程。那么,有没有一种方法可以ack让我们更快地使用这种搜索/操作呢?

答案1

对键 1 到 32 (-k1,32) 进行排序,其中竖条作为分隔符-t'|'
-u表示:仅输出相等运行(组合键)的第一行。
请参阅的选项 man sort的详细信息。sort

sort -t'|' -k1,32 -u infile

当然,上面的代码会产生排序的输出。
但是,如果您想保持与输入文件相同的首次找到行的序列,请使用:

nl -s'|' -ba infile | sort -t'|' -k2,5 -u | sort -t'|' -k1 -n | cut -d'|' -f2-

nl前缀连续的行号。这些行号位于步骤cut之后sort
请注意,第二种方法的输出与特登的 Perl 解决方案。

答案2

彼得的sort方法几乎肯定是最有效的,我建议您使用它。为了多样性,这里有一个 Perl 解决方案:

perl -F"\|" -lane  'push @G,$_ unless ++$k{join("\|",@F[0..31])}>1;
                    END{print join "\n",@G}' file 

相关内容