我在 sh 脚本的上下文中看到sed 's=.*/=='
了,我很困惑。我在 sed 手册或网络搜索 (for sed s=
) 中找不到如何s
使用,而不是s///
. 除了s
我在这里只看到一个潜在的命令=
(打印当前输入行号),但在这种情况下,其余的在做什么......
在 shell 中运行命令会产生与 eg 的输入相同的输出echo 'jkfdsa=335r34'
,而echo 'jkfdsa=335r34' | sed 's/=.*/==/'
根据手册进行替换。还将命令稍微修改为 eg echo 'jkfdsa=3' | sed 's798=.*/==/'
give
sed: -e expression #1, char 11: unterminated 's' command
,因此原始应该具有一些正确的含义。它是什么?
是
=
替代分隔符。使用这些是因为模式包含 a/
(这是更常用的分隔符)。几乎任何字符都可以用作替代分隔符,因此s@.*/@@
或s_.*/__
本来意味着相同的事情。使用普通分隔符,sed
表达式可以写成(表达式想要匹配的文字
/
需要在这里转义)或者,可能更具可读性,(
[...]
字符类中的大多数字符都是文字1)该
sed
表达式的作用是用任何内容替换任何匹配.*/
的内容。这将具有删除所有内容的效果,包括该/
行的最后一个字符。它将删除最后一个/
(不是第一个),因为.*
对任何字符的任何序列进行贪婪匹配。例子:
unterminated 's' command
测试时遇到的错误是由于
7
被用作s
命令的分隔符。表达方式不过会起作用的。
1 ... 除了具有特殊含义的字符,
[...]
例如^
(at the start) 和-
(when not first, second after^
或 last)。中的字符[
和]
也需要特殊处理[...]
,但这超出了这个问题的范围。如果这用于在某个字符串或 shell 变量中获取路径末尾的文件名,那么该
basename
实用程序可能会做得更好(如果路径以斜杠结尾,也会做正确的事情):同样,假设变量不包含换行符,标准 shell 参数替换
${variable##*/}
在其效果上等同于在命令替换中$variable
通过上述sed
表达式传递值,但要快很多倍。变量替换和
basename
实用程序还可以正确处理包含换行符的路径名,这sed
是不会做的(因为它逐行处理其输入)。来自https://backreference.org/2010/02/20/using-different-delimiters-in-sed/:
sed 可以使用任何字符作为“s”命令的分隔符,这是一个鲜为人知的事实。基本上,sed 将“s”后面的任何内容作为分隔符。
所以中间的斜线变成了一个普通的字符。如果我解释正确,你的表达:
也可以写成:
并解释为“删除最后一个斜线之前的任何内容,包括斜线”。
它贪婪地删除之前和
/
自身的所有内容。例子:
输出 :
这里
=
用作正则表达式(.*/)和替换(空)的分隔符。