
想像我有類似以下文字的內容:
2012年和2013年,敏捷的棕色狐狸跳躍
我希望刪除“fox”中的部分,包括四個數字,但僅在第一次出現時刪除,所以我最終得到:
快棕色和 2013
有這樣的東西...:
echo「2012年和2013年快速的棕色狐狸跳躍」\ | sed "s/fox.*\([0-9]\{4\}\)//g"
....帶給我:
快速棕色
因此它刪除了所有內容,包括最後一次出現的四個數字。
有任何想法嗎?
答案1
(「基本」和「擴展」版本)使用的 POSIX 正規表示式sed
不支援非貪婪匹配。 (儘管有一些解決方法,例如使用[^0-9]*
代替.*
,但如果輸入變化很大,它們就會變得不可靠。)
?
您可以透過使用非貪婪量詞在 Perl 中實現您所需要的:
echo "The quick brown fox jumps in 2012 and 2013" \
| perl -pe 's/fox.*?([0-9]{4})//g'
您可能還想刪除多餘的空格。
答案2
假設你想使用僅有的sed 並且您希望匹配的結尾是第一組數字,而不關心數字後面的單字是什麼,這是有效的:
echo「2012年和2013年快速的棕色狐狸跳躍」\ | sed "s/fox[^0-9][^0-9]*[0-9][0-9]* //"
此模式的工作原理是先匹配fox
,後面接著一個或多個非數字[^0-9][^0-9]*
,然後再跟 1 個或多個數字[0-9][0-9]*
。此模式適用於任意數量的數字,而不僅僅是 4 個數字。
echo「2012年和2013年快速的棕色狐狸跳躍」\ | sed "s/fox[^0-9]*\([0-9]\{4\}\) //"
答案3
你沒有指定確切地你的要求是什麼。您可能需要一個多步驟的過程。選擇一個您知道不會出現在輸入中的字串(例如####
):
echo “2012 年和 2013 年,敏捷的棕色狐狸跳過了 42 隻懶狗。” \ | sed\ -e "s/[0-9]\{4\}/&####/" \ -e "s/fox.*####//" \ -e“s/####//”
(為了方便閱讀,命令被過度折疊。)之後-e "s/[0-9]\{4\}/&####/"
注入####
首先四位數。 (警告:這將更改為65536
。6553####6
)
-e "s/fox.*####//"
影響包含fox
和的行####
——即包含至少一個四位數字的行——然後從 到fox
刪除首先四位數。
-e "s/####//"
當然,會清除####
包含四位數字但不包含 的行中剩餘的任何字串fox
。
如果有的話,還要刪除數字後面的一個空格,
echo “2012 年和 2013 年,敏捷的棕色狐狸跳過了 42 隻懶狗。” \ | sed\ -e "s/[0-9]\{4\}/&####/" \ -e "s/fox.*#### //" \ -e "s/fox.*####//" \ -e“s/####//”
警告:您可以添加g
到所有s
命令,但是,由於這仍然使用.*
,這是問題的根源,它仍然無法處理
One fox jumps in 2012 and 2013, another fox will jump in 2014 and 2015.
你可能想要的方式。當然,還有你不想要添加g
到,"s/[0-9]\{4\}/&####/"
因為它會在之後####
注入每一個四位數,打敗整點。然後,"s/fox.*####//"
最終的行為就像"s/fox.*[0-9]\{4\}//"
(您的原始命令已刪除非貢獻字元);即,它會改變
棕色狐狸在 2012 年和 2013 年跳躍得很快。
到
敏捷的棕色狐狸在 2012 年#### 和 2013 年#### 跳躍。
然後到
快棕色。