打印独特的线条


15

是否有比印刷的组合等独特的线条一些更好的解决方案sortuniq


1
“更好”是什么意思?
gabe。

@gabe例如,不需要将整个文件存储在内存中。
Let_Me_Be

sort如果输入太大而无法放入RAM,则某些版本(例如GNU coreutils)将使用临时文件和外部mergesort。而且大多数其他版本都有一个-m选项,因此可以通过对输入进行分块(例如使用split),对每个块进行排序然后合并这些块来明确地完成此操作
jhnc

Answers:


25

要以任何顺序仅打印同一行:

sort -u

要以任何顺序仅打印唯一行:

sort | uniq -u

仅按第一次出现的顺序打印每条相同的行一次:(对于每行,如果尚未看到该行,则将其打印出来,然后在任何情况下都增加看到的计数器)

awk '!seen[$0] {print}
     {++seen[$0]}'

要仅按唯一出现的顺序打印唯一行:(在中记录每行seenlines如果是第一次出现,也要在其中记录;在输入的末尾,请按出现的顺序打印行,但仅打印仅可见的行一旦)

awk '!seen[$0]++ {lines[i++]=$0}
     END {for (i in lines) if (seen[lines[i]]==1) print lines[i]}'

8
怎么样awk '!seen[$0]++ {print}'
asoundmove 2011年

10
甚至更短awk '!seen[$0]++',因为{print}表示空命令。
quazgar

3

的某些(大多数?)版本sort具有直接-u充当uniq零件的标志。虽然可能会取决于实现方式而有些行长限制,但是您已经有了plain的限制sort|uniq


1
sort -u至少回到V7。
geekosaur 2011年

嗯...我以为我记得Solaris或AIX没有那个。不过我错了,他们俩都有。

Solaris和AIX具有-u但不超过512个字符的行长限制。(实际上,我认为Solaris 9 Sun周围的某个位置将其提高到
5120。尽管如此

@geekosaur:确定吗?贝尔系统技术公司的JP Linderman在“构建工作排序例程的理论和实践”中记录了为消除512字节的行长度限制所做的工作。Journal,63,1827-1843(1984)。
乔纳森·勒夫勒

0

Perl对您有用吗?即使重复项不相邻,它也可以使行保持原始顺序。您也可以用Python或编写代码awk

while (<>) {
    print if $lines{$_}++ == 0;
}

可以缩短为

perl -ne 'print unless $lines{$_}++;'

给定输入文件:

abc
def
abc
ghi
abc
def
abc
ghi
jkl

它产生输出:

abc
def
ghi
jkl

$ lines在哪里定义?
2014年

不是。由于没有use strict;use warnings;(实际上,这是strict最相关的),因此%lines在定义它之前不会抱怨使用。如果要严格执行,则my %lines;循环之前必须有一行。还要注意,哈希是%lines; 哈希的一个元素使用$lines{$_}表示法进行引用。
乔纳森·勒夫勒

我认为该sort解决方案可能适用于大量数据(OP担心“将整个文件存储在内存中”)。sort如果数据大于可用内存,将执行核外排序。
Kusalananda

0

对于“ @Gilles 打印唯一行作为此问题的答案”中提到的答案的最后一部分,我试图消除使用两个哈希的需求。

此解决方案适用于:仅按照唯一出现的顺序打印唯一的行:

awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'

在这里,“计数器”存储的每一行的计数与之前处理的计数相似。
最后,我们仅打印计数器值为1的行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.