在使用文本编辑器时,我经常使用PCRE正则表达式进行搜索和替换,而在发现强大的Unix命令行工具(例如)中perl
,awk
或者sed
使用一些高级的多行正则表达式相当复杂并且需要各种形式的正则表达式后,我感到非常不满意。很难记住各种情况的语法。
是否有用于Linux的命令行工具,其中使用更复杂的多行正则表达式进行搜索和替换(对于整个文件中的所有匹配项)非常简单:
magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/' file.txt
即要匹配的正则表达式与我search for
在文本编辑器中放置的正则表达式相同,替换字符串也可以处理多行正则表达式,并且不需要任何复杂的语法吗?
编辑:
对于每个请求,我都会附加一个输入,该输入将使用上面的示例正则表达式进行解释,并说明我希望它实际执行的操作。
像这样的输入:
2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:13 > user joined the channel.
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected
应该产生以下输出:
2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected
regex匹配包含的任何行,[username] joined the channel
并在包含该行的下方查找包含该行的行,[username] disconnected
除非这两行之间有a[username] was kicked from channel.
或[username] was banned from channel.
。
然后,替换字符串将匹配的模式替换为该行之后的每一行,并[username] joined the channel
有效地2016-05-16 06:20:13 > user joined the channel.
从上面的输入中删除了该行。
您很可能没有任何意义,但这只是一个正则表达式示例,与我最近处理过的正则表达式类似。请记住,我不是在使用上面列出的Unix工具针对此特定问题或类似问题寻找解决方案。我正在寻找一种命令行工具,该工具可以使用未经修改的“搜索”和替换字符串,这些字符串在文本编辑器中使用(尤其是Geany,但实际上并不重要),而无需复杂的语法或要求添加一些编程逻辑即可处理多行“搜索”和替换字符串。
我不确定为什么Perl在这里不被接受。在您提供的输入上,此行提供了您要求的输出:
perl -0777p -e 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt
该-e
参数正好是您的第一个参数,magicregextool
除了我添加了/mg
regex修饰符。这可能不是“未修改的”,但似乎也不是没有道理的。如果您不想输入整行,那么此脚本如何magicregextool
:
#!/usr/bin/perl -0777p
BEGIN { $::arg = shift @ARGV; }
eval $arg;
甚至:
#!/bin/sh
perl -0777pe $*
然后,您只需键入:
magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt
这与您的示例相同(同样,除了添加/mg
修饰符之外)。
这样做的另一个好处是,如果您在每个文件上运行多个相关的搜索/替换操作,则可以将它们放在同一脚本中:
#!/usr/bin/perl -0777p
s/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg;
s/(some other\n)matched text/\1/mg;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句