“sort filename | uniq”无法处理大文件。

3

我可以从小型文本文件中删除重复条目,但无法从大型文本文件中删除。
我有一个4MB的文件。
该文件的开头如下:

aa
aah
aahed
aahed
aahing
aahing
aahs
aahs
aal
aalii
aalii
aaliis
aaliis
...

我希望能够去除重复项。
例如,“aahed”出现了两次,我只想让它出现一次。

无论我尝试什么单行命令,这个大列表都不会改变。

如果我输入:sort big_list.txt | uniq | less
我会看到:

aa
aah
aahed
aahed   <-- didn't get rid of it
aahing
aahing   <-- didn't get rid of it
aahs
aahs   <-- didn't get rid of it
aal
...

然而,如果我从这个文本文件的顶部复制一小段单词并在这些数据上重新运行该命令,它会按预期工作。这些程序是否拒绝排序是因为文件太大了吗?我认为4MB并不算很大。它不会输出警告或任何提示。我很快写了一个自己的“uniq”程序,它有同样的行为。它可以对列表的一个小子集进行操作,但对4MB文本文件没有任何作用。我的问题是什么?编辑:以下是十六进制转储:
00000000  61 61 0a 61 61 68 0a 61  61 68 65 64 0a 61 61 68  |aa.aah.aahed.aah|
00000010  65 64 0d 0a 61 61 68 69  6e 67 0a 61 61 68 69 6e  |ed..aahing.aahin|
00000020  67 0d 0a 61 61 68 73 0a  61 61 68 73 0d 0a 61 61  |g..aahs.aahs..aa|
00000030  6c 0a 61 61 6c 69 69 0a  61 61 6c 69 69 0d 0a 61  |l.aalii.aalii..a|
00000040  61 6c 69 69 73 0a 61 61  6c 69 69 73 0d 0a 61 61  |aliis.aaliis..aa|

61 61 68 65 64 0a
a  a  h  e  d  \r

61 61 68 65 64 0d
a  a  h  e  d  \n

解决方案:不同的行分隔符


2
你确定这些行中没有尾随的空格或其他不可见字符吗?uniq 不应该关心文件的大小,因为(由于它要求文件已经排序),它一次只需要在内存中存储几行。 - rra
1
这些行有可能以一种不明显的方式不同吗?例如在空格或换行符方面。 - Joni
没有什么明显的问题,但我想可能是这样。然而,当我将其中一部分粘贴到另一个文件中并再次执行时,它可以正常工作。难道我没有同时复制那些字符吗?也许你是对的,这可能是一些奇怪的不可见ASCII字符,我的剪贴板没有捕捉到...... - Trevor Hickey
1
也许行末有空格导致不同? - Axel
也许你可以使用 head 命令来测试它是否仅在前几行有效? - Larry
@Xploit,你能把它写成答案并接受吗?这将有助于其他人在未来。 - sehe
4个回答

6

sort(1)命令接受-u选项以保证关键字的唯一性。

只需使用:

 sort -u big_list.txt

应该可以工作,但是当我将其输入到“less”中时,我仍然看到重复项。 但是,如果我从“less”的输出中看到那个块,将其粘贴到另一个文件中,并在该文件上运行相同的命令,则会删除重复项。 - Trevor Hickey
2
将其导入文件并使用十六进制编辑器比较所谓的重复行。 - scai
3
@skai 在十六进制中,0a和0d代表不同的行分隔符号,叹气,谢谢。 - Trevor Hickey

4

您可以规范化行分隔符(将CR + LF转换为LF):

sed 's/\r//' big_list.txt | sort -u

3
为了回答max taldykin关于awk '!_[$0]++' file的问题: awk '!_[$0]++' file与以下命令相同:
awk '!seen[$0]++' file

,这与

是相同的。
awk '!seen[$0]++ { print; }' file

表示

awk '
    {
        if (!seen[$0]) {
            print;
        }
        seen[$0]++;
    }' file

以下是重点:

  1. $0 表示当前的 记录,通常是当前行
  2. awk 中的 ACTION 部分是可选的,默认操作是 { print; }
  3. 算术 上下文中,未初始化的变量为 0

这个技巧通常用于支持哈希关联数组的脚本语言中。这里有一个Perl示例 - pynexj

2

除了使用 sort -u,您还可以使用 awk '!_[$0]++' yourfile

来完成相同的操作。


@clarkw,谢谢,但这并不能帮助理解!_[$0]++的含义。 - max taldykin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接