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