SED正则表达式不匹配
我有一个看起来像这样的XML文件:SED正则表达式不匹配
<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-script
现在我遇到了一个匹配多行正则表达式的问题。这是怎么回事?
$ 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
和b a
(其中有一个a
在词的最开始),但不ba
(那里没有)。 (从你选择的标签判断,你可能习惯于Perl?)Perl做出了未来保证,当它位于非单词字符之前时,它总是会逃避它。例如,<
已经没有特殊含义,但\<
保证是表示<
反正但并非所有的正则表达式引擎采用此方法)
编辑用于编辑的问题:。
桑达同时处理一行这是什么使它成为“流编辑器”—的一部分,所以多行正则表达式实际上注定要失败。然而,就你而言,你并不需要多行的正则表达式;您只想找到包含<Notes />
的行和包含</Icon>
的(不同)行,并打印两个(含)之间的所有行。对于这一点,你可以用一个地址范围,指定的/<Notes \/>/
起始地址和/<\/Icon>/
最终地址:(见§3.2 "Selecting lines with sed
" in the GNU sed user's manual.)
sed -n '/<Notes \/>/,/<\/Icon>/ p'
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>
注意的是,以上只是你要的,而不是整个线路的符号出现在符号之间打印。
很高兴知道。谢谢! – 2013-04-04 22:08:48
我以为sed是基于Perl的。谢谢你清理那个。 – 2013-04-04 18:04:52
我知道我可以使用一个范围,但我认为必须有一种方法来在sed中执行多行正则表达式。但是,这很有效。谢谢。 – 2013-04-04 18:52:11
@ davidkennedy85:实际上,sed早于perl,并且perl意图作为更普遍的sed替代品(参见[原始公告](http://groups.google.com/group/comp.sources .unix /树/ browse_frm /月/ 1988年至1902年?_done =%2Fgroup%2Fcomp.sources.unix%2Fbrowse_frm%2Fmonth%2F1988-02%3F&))。 – 2013-04-04 20:29:43