's=.*/==' 在 sed 中做什么?

's=.*/==' 在 sed 中做什么?

我在 sh 脚本的上下文中看到sed 's=.*/==',我很困惑。我在 sed 手册或网络搜索( for sed s=)中找不到如何s使用,而不是s///。除了s我在这里只看到一个潜在的命令=(打印当前输入行号)之外,但在这种情况下其余的命令正在做什么......

在 shell 中运行该命令会产生与 eg 的输入相同的输出echo 'jkfdsa=335r34',而echo 'jkfdsa=335r34' | sed 's/=.*/==/'按照手册进行替换。还稍微修改命令为 例如echo 'jkfdsa=3' | sed 's798=.*/==/'gets
sed: -e expression #1, char 11: unterminated 's' command,所以原始应该有一些正确的含义。它是什么?

答案1

它们=是替代分隔符。使用这些是因为模式包含 a /(这是更常用的分隔符)。几乎任何字符都可以用作替代分隔符,因此s@.*/@@s_.*/__具有相同的含义。使用普通分隔符,sed表达式可以写为

s/.*\///

(表达式想要匹配的文字/需要在这里转义)或者,可能更具可读性,

s/.*[/]//

(字符类中的大多数字符[...]都是文字1

sed表达式的作用是替换任何.*/不匹配的内容。这将具有删除/该行中直到并包括最后一个字符的所有内容的效果。它将删除最多最后的 /(不是第一个)因为.*对任何字符的任何序列进行贪婪匹配。

例子:

$ echo 'a/b/c' | sed 's/.*[/]//'
c

unterminated 's' command测试时出现的错误

s798=.*/==/

是由于7被用作s命令的分隔符。表达方式

s7.*/77

不过会有效的。


1 ...除了具有特殊含义的字符,[...]例如^(在开始时)和-(当不是第一个、第二个之后^或最后一个时)。中的字符[]也需要特殊处理[...],但这超出了这个问题的范围。


如果这用于获取某个字符串或 shell 变量中路径末尾的文件名,那么该basename实用程序可能会做得更好(如果路径以斜杠结尾,也会做正确的事情):

$ basename a/b/c
c
$ basename a/b/c/
c

同样,假设变量不包含换行符,标准 shell 参数替换的效果与在命令替换中通过上述表达式${variable##*/}传递 的值等效,但速度要快很多倍。$variablesed

变量替换和basename实用程序还可以正确处理包含换行符的路径名,但这sed是行不通的(因为它逐行处理输入)。

答案2

https://backreference.org/2010/02/20/using- Different-delimiters-in-sed/:

sed 可以使用任何字符作为“s”命令的分隔符,这是一个鲜为人知的事实。基本上,sed 将“s”后面的任何内容作为分隔符。

所以中间的斜杠就变成了一个普通的字符。如果我的解释正确的话,你的表达是:

s=.*/==

也可以写成:

s/.*\///

并解释为“删除最后一个斜杠之前的所有内容,包括斜杠”。

答案3

它贪婪地删除之前和/自身的所有内容。

例子:

 echo "nsi/wnx/cmedwcm" | sed 's=.*/=='

输出 :

cmedwcm

这里=作为 regex(.*/) 和 replacement(无效的)。

相关内容