如何根据列的值获取唯一行

如何根据列的值获取唯一行

以下输入:

A 13
A 12
B 17
C 33
D 344
C 24
A 5
C 99

我只想获取第一列唯一的行:

B 17
D 344

一个解决方案awk会很好,但其他的解决方案也是可以接受的。

答案1

如果你不介意打乱顺序的话

sort <file> | uniq -uw 1

请参阅 参考资料 来了解man uniq更多信息,但这里是重要的部分。

   -u, --unique
          only print unique lines
   -w, --check-chars=N
          compare no more than N characters in lines

答案2

awk

awk 'NR==FNR { a[$1]++ } NR!=FNR && a[$1]==1' file file

(文件名传递两次)。

编辑:如果该文件来自stdin您需要一个临时副本。像这样的东西:

tmp="$( mktemp -t "${0##*/}"_"$$"_.XXXXXXXX )" && \
    trap 'rm -f "$tmp"' 0 HUP INT QUIT TERM || exit 1
... | tee "$tmp" | awk '...' - "$tmp"

答案3

如果你愿意awk

awk '
    $1 in ARR{
        ARR[$1] = RS;
        next;
    }
    {
        ARR[$1] = $0;
    }
    END{
        for(i in ARR)
            if(ARR[i] != RS)
                print ARR[i];
    }
    ' file

该脚本将行放入数组 ARR 中,其中第一个字段作为索引,整行作为值。如果数组已经具有相同的索引,则将值更改为“\n”(换行)符号。文件结束后打印那些值不等于 «\n» 的数组元素。
请注意 awk 的RS变量newline默认是相等的。

或者你可以这样做sed

sort file |
sed '
    :a;
    $!N;
    s/\(\S\+\s\).*\n\1.*/\1\a/;
    ta;
    /\a/P;
    D;
    '

答案4

perl -lane '
   exists $h{$F[0]} and undef $h{$F[0]},next;

   ( $h{$F[0]}, $h[@h] ) = ( $_, $F[0] );

   END{ print $h{$_} for grep { defined $h{$_} } @h }
' yourfile

代码的操作查看是否之前遇到了第一个字段,那么该名称的键将存在于哈希中,因此我们继续计算undef该特定键的值,因为构建数组是没有意义的无论如何,它最终都会被丢弃。相反,我们通过较小的记忆印记来携带相同的信息。

在第一次看到第一个字段的情况下,我们用%h当前行填充哈希,并同时@h使用该键附加数组。我们执行此步骤是为了保留遇到键的顺序。如果我们不关心顺序,那么我们完全可以取消这一步。

最后,当所有输入都被消化后,在最后的END块中,循环遍历数组的元素@h,并从这些元素中仅找出哈希%h已定义值的元素。请记住,undef价值观意味着必须见过不止一次。

相关内容