繁体   English   中英

sed正则表达式不匹配

[英]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-c​​haracters-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'

会的,在某些系统上,打印aba (其中有一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM