使用 ‘sed’ 替換任何單詞,而不是字元
我知道如何使用
sed
語法[^xxxx]
排除字元,但是如何排除單詞?例如我的變數:var=" Now is the time for all good men to come to the aid of the party"
現在:
echo $var | sed ...
…我想結束:
REPLACED time for all good men to come REPLACED aid REPLACED party
…這應該很簡單,但我不知道該怎麼做。
echo $var | sed -r 's/^[^the]*the/REPLACED/'
… 有點接近,但是
t
h
e
作為單個字元匹配,而不是作為 word 匹配the
。如果有解決方案,我可以將所有內容替換為多次出現中的第一次,甚至可以替換為特定出現,那會更好。
s/.*the/REPLACED/
替換最右邊的所有內容,the
因為那.*
是貪婪的並且希望盡可能多地匹配。
.*
是 0 個或多個 (*
) 字元 (.
)*盡可能多,*並且會愉快地吞噬所有出現的the
不包括最後一個需要由正the
則表達式的以下部分匹配的字元。大約 30 年前,這被
perl
5 修復了,它引入了一個非貪婪版本*
:*?
,它匹配前面的 0 個或更多,但盡可能少:printf '%s\n' "$var" | perl -pe 's/.*?the/REPLACED/'
很少
sed
有添加對這些新perl
運算符的支持。我只知道兩個實現(ssed
with-R
和 ast-open 的 with-P
)。在其他
sed
實現中,當要替換的內容是單個字元(如x
)時,您可以使用除 () 之外s/[^x]*x/REPLACE/
的 0 個或多個 ( )*
字元,盡可能多地表示,並且因為我們排除了 ,所以它將在第一次出現之前儲存。x``[^x]``x``x
*您不能將其用於超過一個字元的字元串,因為只要不包含 “the” ,*就不能說盡可能多的 0 個或多個字元。所以你需要一種不同的方法。
s/the/REPLACEMENT/
替換 的第一次出現the
,因此標準sed
中替換所有字元串直到第一次出現的所有內容的常用方法是用換行符替換它(否則該字元保證不會出現在模式空間中),然後替換該換行符之前的所有內容:sed 's/the/\ /;s/.*\n//'
您可以按如下方式實現,假設
the
線上上最多有一個 的實例:sed -E 's/.*\Wthe(\W.*)/REPLACED\1/'
the
這將用您的替換文本替換最後一次出現的所有內容(請記住,RegExes 是貪婪的) 。
- 它通過將最後一次出現之後的所有內容儲存在擷取組中
the
,並由非單詞字元包圍(以防止部分單詞匹配,例如theoretical
)來實現,包括以 , 結尾的非單詞字元。the``( ... )
- 然後它將用替換文本替換該行,然後是擷取組的內容(稱為,
\1
因為它是搜尋模式中的第一個此類組)。這種有些複雜的方法是必要的,以便終止的字元the
也被轉移到替換文本中。如果您想替換所有內容直到第一次出現,您可能不得不求助於
awk
:awk '(i=match($0,/\Wthe\W/)){print "REPLACED" substr($0,i+4);next} 1'
這將檢查
the
被非單詞字元包圍的字元串是否出現在行上,並將位置儲存在變數i
中。
- 如果
i
為非零,它將列印替換文本和目前輸入行的子字元串,從出現後開始the
,否則跳過執行到下一行。- 如果
i
為零,它只是按原樣列印目前行。