如何在文本文件中保留最后一次出现的重复行?

时间:2017-10-17 12:54:08

标签: bash sed duplicates

我有一个文本文件,其内容可能是重复的。下面是我的txt文件的简化表示。 text表示唯一的字符或单词或短语)。请注意,分隔符----------可能不存在。此外,文件的全部内容由unicode日文和中文字符组成。

EDITED

sometext1
sometext2
sometext3
aaaa
sometext4
aaaa
aaaa
bbbb
bbbb
cccc
dddd
eeee
ffff
gggg
----------
sometext5
eeee
ffff
gggg
sometext6
sometext7:cccc
sometext8:dddd
sometext9
sometext10

我想要实现的是只保留最后一次出现重复的行,如下所示:

sometext1
sometext2
sometext3
sometext4
aaaa
bbbb
sometext5
eeee
ffff
gggg
sometext6
sometext7:cccc
sometext8:dddd
sometext9
sometext10

我在网上找到的最接近的是How to remove only the first occurrence of a line in a file using sed,但这需要您知道要删除的匹配模式。撰写标题时提供的建议主题包括Duplicating characters using sedlast occurence of date,但它们无效。

我在使用Sierra的Mac上。我在script.sh文件中编写可执行命令以逐行执行命令。我使用sedgsed作为我的主流编辑。

4 个答案:

答案 0 :(得分:2)

我不确定您的意图是保留线条的原始顺序。如果是这种情况,您可以这样做:

nl -n rz -ba file
  • sort -k2,2 -t'$\t'为文件添加零填充行号
  • nl按第二个字段对nl的输出进行排序(请注意uniq -f1在行号后面添加一个标签)
  • -f1删除重复项,同时忽略行号字段(sort
  • 最终cut -f2恢复了行的原始顺序,删除了重复项
  • {{1}}删除行号字段,将内容恢复为原始格式

答案 1 :(得分:0)

这个awk非常接近。

假设:

$ cat file
sometext1
sometext2
sometext3
aaaa
sometext4
aaaa
aaaa
bbbb
bbbb
cccc
dddd
eeee
ffff
gggg
----------
sometext5
eeee
ffff
gggg
sometext6
sometext7:cccc
sometext8:dddd
sometext9
sometext10

你可以这样做:

$ awk 'BEGIN{FS=":"} 
        FNR==NR {for (i=1; i<=NF; i++) {dup[$i]++; last[$i]=NR;} next}
        /^$/ {next}
        {for (i=1; i<=NF; i++) 
            if (dup[$i] && FNR==last[$i]) {print $0; next}}
        ' file file
sometext1
sometext2
sometext3
sometext4
aaaa
bbbb
----------
sometext5
eeee
ffff
gggg
sometext6
sometext7:cccc
sometext8:dddd
sometext9
sometext10

答案 2 :(得分:0)

我找到了一个更简单的解决方案,但它在此过程中对文件进行了排序。因此,如果您不介意以排序格式输出,则可以使用以下内容:

$ sort -u input.txt> output.txt

注意:u标志对列出唯一行的文件行进行排序。

答案 3 :(得分:-1)

这可能适合你(GNU sed):

sed -r '1h;1!H;x;s/([^\n]+)\n(.*\1)$/\2/;s/\n-+$//;x;$!d;x' file

将第一行存储在保留空间(HS)中并追加每个后续行。切换到HS并删除与最后一行匹配的任何重复行。同时删除任何分隔线,然后交换回模式空间(PS)。删除除最后一行之外的所有行,该行与HS交换并打印出来。