我正在尝试执行以下操作:
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 会贪婪地将所有东西都消耗到s:.*([^/]*$):\1:
.*
. 你可以在 perl 中使用 non-greedy 修饰符来做到这一点:/
在 sed 中,您可以通过匹配 0 个或多个终止的路径组件来伪造非贪婪:但是,如果您在任何支持 POSIX 的 shell 中执行此操作,您可能会发现使用 shell 参数扩展来删除最长路径匹配更简单:
你让它变得比它需要的更复杂。
让正则表达式的贪婪为您完成工作。将
.*
很快一直过冲到字符串的末尾,但随后它需要匹配一个硬斜杠,因此正则表达式引擎开始回溯,寻找 / 并在返回途中遇到的第一个 / 处停止。=> 字符串的最后一个斜杠。我们只是删除直到这一点,我们隐含地留下最后一个斜线和字符串结尾之后的内容。