答案1
我提供了几种可能的解决方案供您考虑。如果我重复了您已经知道的内容,请原谅我。=)
总结
从 Notepad++ v7.7.1 开始,Notepad++ 有一个名为删除连续重复的行它的作用与下面给出的另外两个解决方案相同(即删除连续重复的行)。
可以使用编辑 → 行操作 → 删除连续重复的行。
看巴特比的回答下面是一个不进行排序即可删除重复行的正则表达式的示例。
原始答案
根据@máté-juhász的评论,对此的接受答案StackOverflow 问题将与您的示例数据一起使用。
在本质上:
打开搜索 → 替换...(Ctrl+ H)在 Notepad++ 中。
在“查找内容:”字段下,输入以下内容正则表达式:
^(.*?)$\s+?^(?=.*^\1$)
将“替换为:”字段留空,并确保在“搜索模式”选项下标记“正则表达式”。
准备好删除线条后,请单击“全部替换”。
请注意,原始答案似乎表明. matches newline
应选中该选项,但评论中的某些人显然没有选中它。对于您的数据,我将其保留为未选中状态,并且似乎效果很好。
例如使用正则表达式
使用 uniq
作为替代方案,假设没有其他选项适合您的需求,如果您有基于 Unix 的 Windows 端口独特实用程序,您可以使用 Notepad++ 将其集成到您的工作流程中。
简而言之,uniq
它执行的功能与上面的正则表达式相同,但可能更可靠。缺点是将它与 Notepad++ 结合使用有点不方便。考虑到这一点,如果您想尝试一下,下面概述了基本步骤。
获取 uniq
首先,您需要一份uniq
适用于 Windows 的。可能有多种选择,但为了简单起见,我建议您使用GnuWin32 CoreUtils 包其中包括uniq
。您目前可以下载轻量级安装程序如果您选择不自行下载和组合 CoreUtils 包组件的压缩版本。
作为提示,对于解决方案中涉及的每个步骤uniq
,我都会跳过使用带空格的路径。Unix 处理目录名称中的空格的方式通常与 Windows 不同,因此从该环境移植的实用程序可能会遇到问题。
作为参考,我不确定 GnuWin32 构建的文件大小限制是什么(如果有的话)uniq
,但我经常轻松地将它用于至少包含几兆字节数据(通常几十万行)的文本文件。
在 Notepad++ 中使用 uniq
安装后uniq
,将类似以下行的内容放入批处理文件中:
C:\path\to\uniq.exe %* > C:\temp\uniq_tmp.txt
notepad++ C:\temp\uniq_tmp.txt
exit()
将此批处理文件保存在您方便使用的永久目录中。为了便于参考,我将称之为uniq_npp脚本。请注意,“temp”可以是任何文件夹,但“tmp”和“temp”通常已存在于 Windows 中。同样,“uniq_tmp.txt”可以是任何您想要的名称,只要它被一致使用即可。
保存后uniq_npp脚本,然后我们就可以将其功能集成到 Notepad++ 中。为此,请打开 Notepad++跑步...菜单(F5)并在出现的字段中输入类似以下内容:
cmd /k C:\path\to\uniq_npp.bat "$(FULL_CURRENT_PATH)"
如果您单击最左边的“运行”按钮,您可以在保存之前测试您的 Notepad++ 命令。
例如运行...对话框
否则,单击“保存...”并适当命名命令。您可以根据需要为其指定键盘快捷键,但这不是必需的。单击“确定”以保留命令设置并将其放置在跑步...下拉菜单以供稍后使用。
例如运行下拉菜单
uniq
假设您对此感兴趣,我会在本答案末尾的“注释”部分中对解决方案的工作原理进行非常简要的概述。
注意事项
关于这个解决方案需要记住的一件重要事情uniq
是绝对需要保存在磁盘上的文件的路径(该文档不能仅在 Notepad++ 中打开)。
这不是您打开的现有文件的问题,但如果您创建新文件或更改现有原始文件,则需要节省在运行之前先uniq_npp脚本文件。否则,操作将失败,并且不会对任何新数据进行排序。
作为一个小的优点,可能值得一提的是,这个保存限制不适用于上面的正则表达式选项。
笔记
排序
提供的解决方案(即初始正则表达式和uniq
)都要求重复的行直接出现在彼此上方才能被删除,例如:
duplicate line X
duplicate line X
这意味着在应用这些操作之前对数据进行排序非常重要。我假设您已经根据示例数据这样做了,但无论如何还是值得一提。
Notepad++ 宏
一个小建议,由于 Notepad++ 的内置行排序操作没有任何实际的键盘快捷键,你可能需要录制一个宏来帮助排序。具体来说,你可以录制一个编辑 → 全选(Ctrl+ A)操作,然后选择其中一个编辑 → 行操作 → 按字典顺序对行进行排序选项。
对于uniq
解决方案,可能还值得考虑将“保存”操作作为排序宏的最后一步进行录制。另请注意,正则表达式选项的步骤(打开替换对话框、输入正则表达式等)也可以录制到方便的宏中。
uniq 解决方案的工作原理
简单来说:
“运行...”行生成一个命令窗口(
cmd /k
),调用uniq_npp脚本并为其提供您选择的当前文件的存储路径。在uniq_npp脚本,此路径是通过
%*
传递给 的通配符捕获的uniq
。然后,来自 的去重数据被uniq
重定向 (>
) 到“uniq_tmp.txt”。最后,批处理文件在新的 Notepad++ 选项卡中打开此清理后的文本,并通过 关闭命令窗口
exit()
。
uniq_npp.bat 改进(?)
关于排序,另一个选择是跳过使用 Notepad++ 对所有内容进行排序。您可能会在排序选项的过程中失去一些灵活性,但您可以通过批处理文件中的额外步骤对项目进行排序窗口排序命令。要添加此步骤,您可以修改第一行uniq_npp脚本如下:
sort %* | C:\path\to\uniq.exe > C:\temp\uniq_tmp.txt
这只是将排序后的数据从 传输sort
到uniq
。如您所见,sort
现在最初捕获数据路径,而不是uniq
。
另一个想法是(可能)使用%*
通配符作为字符串操作的一部分来获取原始文件名,并将例如“uniq_tmp.txt”替换为“original-filename_uniq.txt”之类的内容,以使其更......独特。
潜在的陷阱
默认情况下,Windows
sort
将对数字进行排序,例如1 11 2 21
如果它们前面不包含 0 (例如01, 02, 011, 021
)。
- 虽然 GnuWin32 CoreUtils 软件包确实带有Unix 排序实用程序(它具有比 Windows 更强大的选项
sort
),但这种特定实现(与大多数 GnuWin32 实用程序不同)在 Windows 上的表现有点差。但是,如果您使用 Unix 版本的其他 Windows 端口sort
,则此问题可能不适用,并且可能被证明是总体上更好的选择。
答案2
我发现这对于无序的项目非常有效:
搜索:
(?s)^(.*?)$\s+?^(?=.*^\1$)
单击“全部替换”,在“替换为:”字段中不输入任何内容。
编辑:
以下是具体步骤:
(?s) 点也匹配换行符。
^ 行首
(.*?)$ 通过非贪婪地匹配零个或多个任意字符来建立第一个捕获组,直到遇到第一个行尾。
\s+? 非贪婪地匹配一个或多个空格字符
^ 行首(再次)
(?= 使用非捕获组的正向前瞻(此模式必须匹配,但不存储)。
.*^\1$) 贪婪地匹配零个或多个字符,持续到新行,其中整行与第一个捕获组匹配。
因此,正则表达式会创建一个捕获组,然后搜索文档中的所有行,直到找到与该行完全匹配的行并用任何内容替换原始行。
附录:我当时没有想到这一点,我向正则表达式的创建者道歉,但我相信斯科特是正确的,因为我使用的是别人创建的正则表达式的一个略微修改的版本。如果我要猜测它的来源,我认为它更有可能是他给出的链接中实际提到的答案,可以在这里。
最后,请接受我的道歉:
- 没有给予应有的赞扬。我当时没有想到这一点,但我应该想到。
- 没有完全解释我提供的答案,这会增加人们对正在发生的事情的理解,因此他们可能能够将这些信息用于解决其他问题。
- 没有更快地回复 Scott 的评论。我对使用这个网站并不十分熟练(因此我的分数很低),直到今天才想起检查我的通知。
我错了!
答案3
谢谢,但 regex 和 uniq 仅检测到相邻的重复行。使用此 awk 脚本代替 awkuniq-npp.bat,它与 Notepad++ 兼容。4 行 bat 文件:
C:\pathto\awk.exe'(a[$0]++==0)'%*>%*.1 删除 %* 移动 %*.1 %* 出口()运行命令:
cmd /k C:\pathto\awkuniq-npp.bat “$(FULL_CURRENT_PATH)”
它在删除/移动后使用自动重新加载来替换相同的文件名
答案4
我使用以下搜索/替换正则表达式(对行进行排序后),我发现它更直观、更容易理解:
Find: (.*)\r?\n(\1\r?\n)+
Replace with: \1\r\n
说明:
- 查找“任何内容”(一行文本)后跟一个新行(\n 或 \r\n):。\r?\n
- 将该行的内容保存在变量中:(.)\r?\n
- 查找同一行重复出现一次或多次的情况: (.*)\r?\n(\1\r?\n)+
替换:- 用该行本身和新行替换以上所有内容:\1\r\n
希望有帮助,
sb3k