簡體   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