这个问题意味着与语言无关.只使用正则表达式,我可以找到并替换文件中的重复行吗?
请考虑以下示例输入和我想要的输出;
输入>>
11
22
22 <-duplicate
33
44
44 <-duplicate
55
Run Code Online (Sandbox Code Playgroud)
输出>>
11
22
33
44
55
Run Code Online (Sandbox Code Playgroud)
Ben*_*mes 84
Regular-expressions.info有一个关于从文件中删除重复行的页面
这基本上归结为搜索这个oneliner:
^(.*)(\r?\n\1)+$
Run Code Online (Sandbox Code Playgroud)
......并替换为\1.
注意:Dot必须与Newline不匹配
说明:
将插入符号只在一行的开始匹配.所以正则表达式引擎只会尝试匹配那里的正则表达式的其余部分.该点与明星组合只是相匹配的整条生产线,无论它的内容,如果有的话.括号将匹配的行存储到第一个反向引用中.
接下来我们将匹配行分隔符.我将问号放入
\r?\n以使这个正则表达式适用于Windows(\r\n)和UNIX(\n)文本文件.所以到目前为止,我们匹配一条线和下面的换行符.现在我们需要检查这个组合是否后跟同一行的副本.我们这样做只是为了
\1.这是第一个支持我们匹配的行的反向引用.反向引用将匹配相同的文本.如果反向引用无法匹配,则丢弃正则表达式匹配和反向引用,并且正则表达式引擎在下一行的开头再次尝试.如果反向引用成功,则正则表达式中的加号将尝试匹配该行的其他副本.最后,美元符号强制正则表达式引擎检查反向引用匹配的文本是否是完整的行.我们已经知道反向引用匹配的文本前面有一个换行符(由\ r?\n匹配).因此,我们现在检查它是否也跟着换行符,或者它是否在使用美元符号的文件末尾.
整场比赛变成
line\nline(或line\nline\nline等).因为我们正在进行搜索和替换,所以从文件中删除行,它们的副本以及它们之间的换行符.由于我们要保留原始行,而不是重复行,因此我们使用\1替换文本将原始行放回原处.
请参阅我的请求以获取更多信息,我现在以一种简单的方式进行答复。
如果顺序无关紧要,只需
排序-u
会成功的
如果顺序很重要,但是您不介意重新运行多次(这是vim语法),则可以使用:
%s / \(。* \)\(\ _。* \)\(\ 1 \)/ \ 2 \ 1 / g
保留最后一次出现,或
%s / \(。* \)\(\ _。* \)\(\ 1 \)/ \ 1 \ 2 / g
保留第一次出现。
如果您确实想重新运行多次,那么这会比较困难,因此在进行此操作之前,请在问题中回答!
编辑:在您的编辑中您不是很清楚,但是您似乎只想删除一次通过重复的ADJACENT行!好吧,这要容易得多!
一个简单的:
/(.*)\1*/\1/
Run Code Online (Sandbox Code Playgroud)
(/\(.*\)\1*/\1/在vim中),即搜索(.*)\1*并替换为just \1就能解决问题
在 RegexBuddy 中,您可以按如下方式执行此操作:
如果您只对一个文件执行此操作,则可以使用“测试”选项卡而不是“GREP”选项卡。在“测试”选项卡上加载文件,然后单击主工具栏中的“替换”按钮。