如何在文本文件中查找重复行并打印它们?

9

我有一个包含大约1200行的文本文件,其中一些是重复的。

我该如何找到文件中的重复行(不考虑大小写),并将其文本打印在屏幕上,以便我可以找到它们?我不想删除它们或做任何其他操作,只是想找到可能存在的重复行。


你知道如何(1)从文件中获取行 (2)比较字符串吗?如果两者都是肯定的,那么你只需要解决一个有效比较方案的问题。那么你在这个问题的哪个部分卡住了呢? - dmckee --- ex-moderator kitten
@dmckee 是的,对于两个是的,但不排除其他情况。对于一个则是否定的。 - samiles
我非常抱歉对在座的所有人:( - samiles
评论的目的不是让你感到难受,而是帮助你写出更好的问题。在这里,你实际上有两个问题:(1)如何执行字符串的大小写不敏感比较,以及(2)如何高效地存储已经被查看的行并与它们进行比较。第一个问题可能已经在 Stack Overflow 上得到了回答,因此你可以搜索一下。第二个问题本来应该更加明确些。无论如何,我看到你已经得到了很好的答案。 - dmckee --- ex-moderator kitten
3个回答

28

使用set非常简单:

with open('file') as f:
    seen = set()
    for line in f:
        line_lower = line.lower()
        if line_lower in seen:
            print(line)
        else:
            seen.add(line_lower)

我没有尝试过这段代码,但你不是必须像f.read()或f.readlines()这样做才行,而不仅仅是f? - tehmisvh
1
@tehmisvh -- 不是的。 file对象是迭代器。您可以直接对它们进行迭代。 :) -- 如果你问我,那真是一个很酷的设计决定。 - mgilson
完美运行。打印出的行之间有很大的空隙,几乎像是它也打印了黑色的线条,但无论如何它都能正常工作。谢谢。 - samiles
2
请注意,如果一行出现三次,它将在结果中打印两次。这可能不是什么问题。 - Steven Rumbalski
1
巨大的空白行是空行。由于空行出现了不止一次,它们被打印出来了。为了抑制这种情况,请将if语句更改为if line_lower in seen and line_lower.strip():。或者在for语句的第一行添加if not line.strip(): continue - Steven Rumbalski
显示剩余3条评论

9

由于只有1200行代码,因此您也可以使用collections.Counter()

>>> from collections import Counter

>>> with open('data1.txt') as f:
...     c=Counter(c.strip().lower() for c in f if c.strip()) #for case-insensitive search
...     for line in c:
...         if c[line]>1:
...             print line
... 

如果 data1.txt 的内容如下:
ABC
abc
aBc
CAB
caB
bca
BcA
acb

输出结果为:

cab
abc
bca

2

查找不区分大小写的重复项

这种方法无法提供行号,但是可以给出一个重复行的列表,您可以进一步进行调查。例如:

tr 'A-Z' 'a-z' < /tmp/foo | sort | uniq -d

示例数据文件

# /tmp/foo
one
One
oNe
two
three

上面列出的管道将正确产生:

一个

查找行号

然后可以使用grep查找相关的行号,例如:

grep --ignore-case --line-number one /tmp/foo

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