Sed
為什麼這個 sed 命令不替換倒數第三個“and”?
2020 年 5 月 26 日更新
看起來這是一個錯誤,所以我送出了一個錯誤。它的 ID 是#41558。
我只是在搞亂
sed
,我想出了這個練習:替換倒數第三次出現的“and”(這個詞,而不是子字元串),創建:dog XYZ foo and bar and baz land good
我以為這行得通
echo 'dog and foo and bar and baz land good' | sed -E 's/(.*)\band\b((.*\band\b){2})/\1XYZ\2/'
但它實際上取代了倒數第二次出現的“and”。我能想到的唯一解釋是它包括“土地”作為其中之一
\band\b
,但不應該是這種情況,因為我包括了\b
邊界這個詞?
這很難做到,因為
sed
不支持環視等(就像你可以在 PCRE 中做的那樣)。反轉字元串並從頭開始替換第三次出現的反轉單詞會更容易,然後再次反轉。$ echo 'dog and foo and bar and baz land good' | rev | sed 's/\<dna\>/XXX/3' | rev dog XXX foo and bar and baz land good
至於為什麼你的表達不起作用,這看起來像一個錯誤。反向引用
\3
似乎是 stringbaz land
,好像\b
之前and
的 in.*\band\b
從來沒有任何效果。命令
sed -E 's/(.*)\<and\>((.*\<and\>){2})/\1XYZ\2/'
似乎在 OpenBSD 上使用其本機
sed
(使用\<
and\>
而不是\b
)做正確的事情。
sed
我還沒有找到針對 GNU或 GNU的現有錯誤報告glibc
,儘管如果它至少與glibc 錯誤 25322相關(因為,見下文),我不會感到驚訝。您可以通過更詳細一些來解決它:
sed -E 's/(.*)\band\b(.*\band\b.*\band\b)/\1XYZ\2/'