有一个使用标准实用程序的简单方法(这并不是显而易见的方法),它不需要大的内存即可运行sort
,在大多数实现中,该方法对大型文件进行了特定的优化(一种良好的外部排序算法)。此方法的优点是,它仅在专用实用程序内的所有行上循环,而在解释型语言内不循环。
<input nl -b a -s : | # number the lines
sort -t : -k 2 -u | # sort and uniquify ignoring the line numbers
sort -t : -k 1n | # sort according to the line numbers
cut -d : -f 2- >output # remove the line numbers
如果所有行都以非空格字符开头,则可以省去一些选项:
<input nl | sort -k 2 -u | sort -k 1n | cut -f 2- >output
对于大量重复,仅需要将每行的单个副本存储在内存中的方法将表现更好。通过一些解释开销,有一个非常简洁的awk脚本(已由enzotib发布):
<input awk '!seen[$0]++'
不太简洁:!seen[$0] {print} {seen[$0] += 1}
,即打印当前行(如果尚未看到),然后递增seen
该行的计数器(未初始化的变量或数组元素的数值为0)。
对于较长的行,可以通过仅保留每行的不可伪造的校验和(例如,加密摘要)来节省内存。例如,使用SHA-1,您只需要20个字节加上每行恒定的开销。但是计算摘要相当慢。仅当您具有快速的CPU(尤其是使用硬件加速器来计算摘要的CPU)并且相对于文件大小和足够长的行没有足够的内存时,此方法才会获胜。没有基本的实用程序可让您为每一行计算校验和。您将不得不承担Perl / Python / Ruby /…的解释开销,或者编写专用的编译程序。
<input perl -MDigest::MD5 -ne '$seen{Digest::MD5::md5($_)}++ or print' >output