我正在試驗sed,最近我注意到有趣的行爲。但是,我無法找到任何描述它的文檔。Sed:在's'命令行匹配正則表達式的反向引用substring
假設我們有文件名爲 'sedtest':
$cat sedtest | sed '/\([[:digit:]]\+\)/s,,(\1),'
hello (0) world
example
(4) sed
Phone number: (123)-456-789
這是非常容易理解的sed腳本:
$cat sedtest
hello 0 world
example
4 sed
Phone number: 123-456-789
接下來,我將通過sed的運行
- 首先,它通過regexp
\([[:digit:]]\+\)
匹配字符串,表示「匹配包含1個或多個數字的字符串」。請注意,我還使用s
命令式\(
和\)
圓括號在此標記子字符串(是否允許?)。 - 如果匹配,則執行
s
命令s,,(\1),
(帶有空的正則表達式字段),表示「用(\1)
替換匹配的子字符串」。
起初我認爲它應該失敗,出現錯誤,因爲\1
和類似的反向引用應該只工作從s
命令匹配字段,它是在這種情況下,空的字符串。
但結果好像是s,\([[:digit:]]\+\),(\1),
腳本(\regexp\
匹配器移到s
命令匹配器字段中)!
所以,問題是:它是正常的(即,它是希望的行爲),就好像它們是由s/regexp/replace/
命令匹配反向引用從s//replace/
命令通過\regexp\
規則匹配的文本的子串?
P.S.
我的sed版本:GNU的sed 4.2.1
背後問題的動機是這樣,你可以這樣做:
sed '/^Number: \([[:digit:]]\+\)$/{s,,#NUMBER: (\1),;p;d};q 1'
,即
/^Number: \([[:digit:]]\+\)$/
- 每個字符串匹配Number: 12345
和匹配的情況:s,,#NUMBER: (\1),
- 用替換它p
- 打印d
- 圖案清晰的空間,和開始新的循環(取新行和開始解析從開始腳本表達式)
q 1
- 出口與代碼1,該命令僅在步驟1中沒有發生匹配時執行(因爲d
命令存在) - 它檢查'不匹配'的情況,在我的情況下這意味着'不允許字符串'並且必須導致錯誤。
主這裏特技正在執行p
和d
命令置換髮生,使用「正常」 s/match/replace/
命令時,這是不可能的之後。