如果第一列重复,则删除文件中的整行

如果第一列重复,则删除文件中的整行

我有一个包含两列和 1000 万行的文件。第一列包含许多重复值,但第 2 列中有一个不同的值。我想删除重复的行并希望仅保留一个使用awk.注意:文件按第 1 列中的值排序。例如:

1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.

预期产出

1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.

答案1

几个方法:

  1. awk

    awk '!a[$1]++' file
    

    这是一种非常简洁的写法:

    awk '{if(! a[$1]){print; a[$1]++}}' file
    

    因此,如果当前第一个字段 ( $1) 不在a数组中,则打印该行并将第一个字段添加到a。下次我们看到该字段时,它将位于数组中,因此不会被打印。

  2. Perl

    perl -ane '$k{$F[0]}++ or print' file
    

    或者

    perl -ane 'print if !$k{$F[0]}++' file
    

    这个和上一个基本是一样的awk。这-n导致 perl 逐行读取输入文件并将提供的脚本应用-e到每一行。将-a自动在空白处分割每一行并将结果字段保存在@F数组中。最后,将第一个字段添加到%k哈希中,如果尚不存在,则打印该行。同样的事情可以写成

    perl -e 'while(<>){
                @F=split(/\s+/); 
                print unless defined($k{$F[0]}); 
                $k{$F[0]}++;
             }' file
    
  3. 核心工具

    rev file | uniq -f 1 | rev
    

    此方法的工作原理是首先反转行,file这样如果行是 12 345,那么现在将是 543 21。然后我们使用uniq -f 1忽略第一个字段,即 543 所在的列。其中有字段file。此处使用的uniq效果是过滤掉任何重复的行,每行仅保留 1 个。最后,我们通过另一个相反的操作将线条恢复到原来的顺序。

  4. GNU 排序(如建议作者:@StéphaneChazelas)

    sort -buk1,1
    

    -b标志忽略前导空格,并且该-u方法仅打印唯一字段。聪明的一点是-k1,1.该-k标志设置要排序的字段。它采用通用格式,即排序时-k POS1[,POS2]只通过POS2查看字段。POS1所以,-k1,1意味着只看第一个字段。根据您的数据,您可能还想添加以下选项之一:

     -g, --general-numeric-sort
          compare according to general numerical value
     -n, --numeric-sort
          compare according to string numerical value
    

答案2

如果第一列始终为 5 个字符长,您可以简单地使用uniq

uniq -w 5 file

如果没有,请使用awk

awk '$1!=a{print $0; a=$1}' file

对于大文件,第一个肯定会更快。

相关内容