用于重复行检索的Linux命令或/和脚本

时间:2016-10-18 15:17:14

标签: linux shell awk duplicates

我想知道是否有一种简单的方法可以在包含许多条目(大约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脚本是否更适合此任务或者如果有其他类型的命令可以做到这一点。

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你可以使用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

答案 2 :(得分:0)

这是一种结合了一些命令行工具的方法:

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