【问题标题】:Linux command or/and script for duplicate lines retrieval用于重复行检索的 Linux 命令或/和脚本
【发布时间】:2016-10-18 15:17:13
【问题描述】:

我想知道是否有一种简单的方法可以在包含许多条目(大约 200.000 或更多)的文本文件中找到重复的行,并输出带有重复行号的文件,从而保持源文件的完整性。例如,我得到一个文件,其中包含这样的推文:

1. i got red apple
2. i got red apple in my stomach
3. i got green apple
4. i got red apple
5. i like blue bananas
6. i got red apple
7. i like blues music
8. i like blue bananas
9. i like blue bananas

我希望输出是一个单独的文件,如下所示:

4
6
8
9

其中数字将指示具有重复条目的行(不包括第一次出现的重复项)。另请注意,匹配模式必须是完全相同的句子(如第 1 行与第 2 行不同,第 5 行与第 7 行不同等等)。

我在sort | uniq 中找到的所有内容似乎都与整个句子不匹配,而只与句子的第一个单词匹配,所以我正在考虑 awk 脚本是否更适合此任务,或者是否有另一种类型的可以做到这一点的命令。

我还需要第一个文件是完整的(不以任何方式排序或重新排序)并且只获取如上所示的行号,因为我想从两个文件中手动删除这些行。第一个文件包含推文,第二个文件包含这些推文的标签,所以我想删除两个文件中包含重复推文的行,保留第一次出现。

【问题讨论】:

  • 第一个文件是否真的包含行号,还是只是为了说明?
  • @BenjaminW。不,它没有。我猜你的解决方案只用 sort without -k 2 就行了?
  • 我的解决方案假定没有行号,并使用nl 添加它们。 -k 2 是必需的。

标签: linux shell awk duplicates


【解决方案1】:

你可以试试这个awk:

awk '$0 in a && a[$0]==1{print NR} {a[$0]++}' file

根据评论,

awk '$0 in a{print NR} {a[$0]++}' file

输出:

$ awk '$0 in a && a[$0]==1{print NR} {a[$0]++}' file
4
8

$ awk '$0 in a{print NR} {a[$0]++}' file
4
6
8
9

【讨论】:

  • 谢谢,这与我正在寻找的非常接近。有没有办法让它打印所有重复的行,而不仅仅是遇到的第一行?
  • 也许我可以循环这个命令并从文件中删除每个循环中的行,但我不知道何时停止。我想当打印行的文件为空时..但我该怎么做呢?我刚刚开始使用 shell 脚本。
【解决方案2】:

你可以使用 python 脚本来做同样的事情。

f = open("file")
lines = f.readlines()
count = len (lines)
i=0
ignore = []
for i in range(count):
    if i in ignore:
        continue
    for j in range(count):
        if (j<= i):
            continue
        if lines[i] == lines[j]:
            ignore.append(j)
            print j+1

输出:

4
6
8
9

【讨论】:

  • 像魅力一样工作!谢谢!!
  • 写python脚本有时可以节省很多时间!!
【解决方案3】:

下面是结合几个命令行工具的方法:

nl -n ln file | sort -k 2 | uniq -f 1 --all-repeated=prepend | sed '/^$/{N;d}' |
cut -f 1

这个

  • nl 对行进行编号,左调整不带前导零 (-n ln)
  • 使用sort 对它们进行排序(忽略第一个字段,即行号)
  • 查找重复行,忽略带有uniq 的第一个字段; --all-repeated=prepend 在每组重复行之前添加一个空行
  • 使用sed 删除所有空行和每组重复项中的第一个行
  • 使用cut 删除行号以外的所有内容

这是不同阶段的输出结果:

$ nl -n ln file
1       i got red apple
2       i got red apple in my stomach
3       i got green apple
4       i got red apple
5       i like blue bananas
6       i got red apple
7       i like blues music
8       i like blue bananas
9       i like blue bananas
$ nl -n ln file | sort -k 2
3       i got green apple
1       i got red apple
4       i got red apple
6       i got red apple
2       i got red apple in my stomach
5       i like blue bananas
8       i like blue bananas
9       i like blue bananas
7       i like blues music
$ nl -n ln file | sort -k 2 | uniq -f 1 --all-repeated=prepend

1       i got red apple
4       i got red apple
6       i got red apple

5       i like blue bananas
8       i like blue bananas
9       i like blue bananas
$ nl -n ln file | sort -k 2 | uniq -f 1 --all-repeated=prepend | sed '/^$/{N;d}'
4       i got red apple
6       i got red apple
8       i like blue bananas
9       i like blue bananas
$ nl -n ln file | sort -k 2 | uniq -f 1 --all-repeated=prepend | sed '/^$/{N;d}' | cut -f 1
4
6
8
9

【讨论】:

  • 感谢这是一个不错的方法。它在我的数据集样本(有 1000 个条目)中运行良好,但在我的 125 万条推文的大数据集上使用它时,在开始时会添加一些空白行。
  • @lopsi 那么输入文件中可能有空行。不确定您的真实输入是什么样的。
猜你喜欢
  • 2011-09-20
  • 2014-11-26
  • 1970-01-01
  • 2018-02-11
  • 2020-06-21
  • 2012-10-01
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
相关资源
最近更新 更多