[英]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.