代码之家  ›  专栏  ›  技术社区  ›  ebattulga

如何使用正则表达式查找和删除文件中的重复行?[关闭]

  •  32
  • ebattulga  · 技术社区  · 15 年前

    这个问题的意思是语言不可知论。仅使用正则表达式,我可以在文件中查找和替换重复行吗?

    请考虑下面的示例输入和我想要的输出;

    输入& gt;

    11
    22
    22  <-duplicate
    33
    44
    44  <-duplicate
    55
    

    输出>>

    11
    22
    33
    44
    55
    
    3 回复  |  直到 6 年前
        1
  •  67
  •   Cullub    9 年前

    regular-expressions.info的网页位于 Deleting Duplicate Lines From a File

    这基本上归结为搜索这一行:

    ^(.*)(\r?\n\1)+$
    

    …替换为 \1 .
    注意:点不能与换行符匹配

    说明:

    这个 caret 仅在行首匹配。因此,regex引擎将只尝试匹配其中的其余regex。这个 dot star 组合只匹配整行,不管它的内容是什么,如果有的话。括号将匹配的行存储到第一个backreference中。

    接下来我们将匹配行分隔符。我把 question mark 进入之内 \r?\n 使此regex与两个窗口一起工作( \r\n 和UNIX( \n )文本文件。到目前为止,我们匹配了一条线和下面的换行符。

    现在我们需要检查这个组合后面是否有同一行的副本。我们这么做只是为了 1 . 这是保存我们匹配的行的第一个回溯引用。backreference将匹配相同的文本。

    如果backreference不匹配,则将丢弃regex匹配和backreference,并且regex引擎将在下一行的开头重试。如果backreference成功,则 plus symbol 在正则表达式中,将尝试匹配行的其他副本。最后, dollar symbol 强制regex引擎检查backreference匹配的文本是否是完整的行。我们已经知道backreference匹配的文本前面有一个换行符(匹配\r?\ n)。因此,我们现在使用 dollar sign .

    整个比赛变成 line\nline (或) line\nline\nline 等等)。因为我们正在进行搜索和替换,所以行、其重复项以及它们之间的换行符都将从文件中删除。因为我们要保留原始行,而不是重复行,所以我们使用 1 作为替换文本将原始行放回。

        2
  •  4
  •   Davide    15 年前

    查看我的请求以获取更多信息,我在 简易方法 现在。

    1. 如果订单无关紧要,只需

      排序-U

      会成功的

    2. 如果顺序很重要,但您不介意重新运行多个过程(这是vim语法),则可以使用:

      %S/\(.*\)\(\.*\)\(\1\)/\2\1/G

      保留最后一个事件,或

      %S/\(.*\)\(\.*\)\(\1\)/\1\2/G

      保留第一次出现。

    如果你真的介意多次传球,比这更难,所以在我们开始之前,请在问题中这样说!

    编辑:在您的编辑中,您不是很清楚,但看起来您只需要删除一个单次重复的相邻行!好吧,那就容易多了!

    简单:

    /(.*)\1*/\1/
    

    ( /\(.*\)\1*/\1/ 在vim)中,即搜索 (.*)\1* 把它换成 \1 会成功的

        3
  •  3
  •   Jan Goyvaerts    14 年前

    在RegexBuddy中,您可以执行以下操作:

    1. 在“库”选项卡上,如果默认情况下未加载,则加载regexbuddy.rbl库。
    2. 在查找框中,键入“duplicate”
    3. 单击使用按钮加载“删除重复行”regex。
    4. 在grep选项卡上,指定要从中删除重复项的文件的文件夹和文件掩码。
    5. 在grep按钮的下拉菜单中,选择Execute。

    如果只在一个文件上执行此操作,则可以使用“测试”选项卡而不是“grep”选项卡。在“测试”选项卡上加载文件,然后单击主工具栏中的“替换”按钮。