以下输入:
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
价值观意味着必须见过不止一次。