[英]sed regular expression not matching
我有一个看起来像这样的XML文件:
<Group>
<Name>Awesome Group</Name>
<Notes />
<Date>2013-04-04</Date>
<Expires>False</Expires>
<Icon>7</Icon>
<Tags />
</Group>
我正在尝试使用以下命令打印<Notes />
和</Icon>
之间的所有内容:
$ sed -n '/\<Notes \/\>/ p' file.xml
注意,我在转义左,右括号以及右斜杠之前。 这没有返回匹配,我觉得很奇怪。
更奇怪的是该命令有效:
$ sed -n '/<Notes \/>/ p' file.xml
因为我没有转义左括号和右括号,所以此命令为什么起作用?
编辑
ruakh很有帮助地指出sed有不同的实现方式,并且不需要转义左括号和右括号(我认为sed对正则表达式使用Perl语法)。 我在Unix和Linux上发现了另一篇也有帮助的文章: https : //unix.stackexchange.com/questions/32907/what-characters-do-i-need-to-escape-when-using-sed-in-a -SH-脚本
现在,我遇到了与多行正则表达式匹配的问题。 为什么这不起作用?
$ sed -n -r '/^<Notes \/>[\S\s]*?<\/Icon>$/ p' file.xml
我试过有和没有-r
(扩展模式),使用和不使用^
和$
,用.*
代替[\\S\\s]*
,都没有比赛
在sed中, <
和>
没有特殊含义,但是\\<
和\\>
有时会起作用 :在某些实现中,它们表示“单词的开始”和“单词的结束”。 例如,此Bash命令:
{ echo a ; echo ba ; echo b a ; } | sed -n '/\<a/ p'
会的,在某些系统上,打印a
和ba
(其中有一个a
在词的最开始),但不ba
(那里没有)。
(从您选择的标签来看,您可能会习惯于Perl?Perl保证了面向未来的保证, \\
在非单词字符之前会始终转义。例如, <
没有特殊含义,但是\\<
无论如何都保证表示<
。但是并非所有的正则表达式引擎都采用这种方法。)
编辑已编辑的问题:
Sed一次处理一行,这就是使其成为“流编辑器”的一部分-因此,多行正则表达式注定会失败。 但是,根据您的情况,您实际上不需要多行正则表达式。 您只想查找包含<Notes />
的行和包含</Icon>
的(不同)行,并打印这两个(包括)之间的所有行。 为此,可以使用地址范围 ,指定/<Notes \\/>/
的开始地址和/<\\/Icon>/
的结束地址:
sed -n '/<Notes \/>/,/<\/Icon>/ p'
(请参阅GNU sed用户手册中的第3.2节“选择sed
行” 。)
sed是用于在一行上进行简单替换的出色工具,对于其他任何文本操作,都应使用awk。 这是一个GNU awk解决方案:
$ gawk -v RS='\0' '{print gensub(/.*(<Notes \/>.*<\/Icon>).*/,"\\1","")}' file
<Notes />
<Date>2013-04-04</Date>
<Expires>False</Expires>
<Icon>7</Icon>
请注意,以上只是在您要的符号之间打印,而不是符号出现的整个行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.