Sed
無法匹配組
我正在嘗試執行以下操作:
echo "/Users/anon/Applications/Chrome Apps.localized/Spotify.app" | sed -E 's:([^\/]*$).*:\1:'
我認為它會擷取
Spotify.app
並用它替換整個字元串,但這不起作用。相反,我得到了整個字元串。所以,我想也許我的正則表達式是錯誤的,所以我做了下面的測試:
echo "/Users/anon/Applications/Chrome Apps.localized/Spotify.app" | sed 's:[^\/]*$:PWA.app:'
但我得到了預期的輸出:
/Users/anon/Applications/Chrome Apps.localized/PWA.app
.所以,我不確定我在這裡做錯了什麼。為什麼分組時相同的正則表達式不匹配?
你讓它變得比它需要的更複雜。
sed -e 's:.*/::'
讓正則表達式的貪婪為您完成工作。將
.*
很快一直過衝到字元串的末尾,但隨後它需要匹配一個硬斜杠,因此正則表達式引擎開始回溯,尋找 / 並在返回途中遇到的第一個 / 處停止。=> 字元串的最後一個斜杠。我們只是刪除直到這一點,我們隱含地留下最後一個斜線和字元串結尾之後的內容。
它正在匹配,然後您轉身並將匹配的值替換回您找到它的位置。請注意,之後
.*
不能匹配任何內容。$
大概你想要類似的東西,
s:.*([^/]*$):\1:
除了那不起作用,因為 sed 會貪婪地將所有東西都消耗到.*
. 你可以在 perl 中使用 non-greedy 修飾符來做到這一點:$ echo "/Users/anon/Applications/Chrome Apps.localized/Spotify.app" | perl -pe 's:.*?([^/]*$):\1:' Spotify.app
/
在 sed 中,您可以通過匹配 0 個或多個終止的路徑組件來偽造非貪婪:$ echo "/Users/anon/Applications/Chrome Apps.localized/Spotify.app" | sed -E 's:([^/]*/)*(.*)$:\2:' Spotify.app
但是,如果您在任何支持 POSIX 的 shell 中執行此操作,您可能會發現使用 shell 參數擴展來刪除最長路徑匹配更簡單:
$ var="/Users/anon/Applications/Chrome Apps.localized/Spotify.app" $ echo "${var##*/}" Spotify.app