如何使用 sed 替换字符串中最后一次出现的字符?

mai*_*ash 44 sed text-processing

如何使用空格仅替换字符串中最后一次出现的“-” sed

例如:

echo $MASTER_DISK_RELEASE
swp-RedHat-Linux-OS-5.5.0.0-03
Run Code Online (Sandbox Code Playgroud)

但我想得到以下输出(用空格替换最后一个连字符 [“-”])

swp-RedHat-Linux-OS-5.5.0.0 03
Run Code Online (Sandbox Code Playgroud)

jim*_*mij 60

你可以用 single 做到这一点sed

sed 's/\(.*\)-/\1 /'
Run Code Online (Sandbox Code Playgroud)

或者,使用扩展正则表达式:

sed -r 's/(.*)-/\1 /'
Run Code Online (Sandbox Code Playgroud)

关键是它sed非常贪婪,所以尽可能多地匹配之前的字符-,包括其他字符-

$ echo 'swp-RedHat-Linux-OS-5.5.0.0-03' | sed 's/\(.*\)-/\1 /'
swp-RedHat-Linux-OS-5.5.0.0 03
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不是便携式的。一些非 GNU 版本的 `sed` 不支持模式匹配。在这种情况下,您将需要其他东西,无论是 `perl -pne 's/(.*)-/$1 /'` 或 @Thor 的参数扩展解决方案或其他东西。 (4认同)

Tho*_*hor 35

您还可以使用bash 参数扩展来处理此问题:

s=swp-RedHat-Linux-OS-5.5.0.0-03
echo ${s%-*} ${s##*-}
Run Code Online (Sandbox Code Playgroud)

输出:

swp-RedHat-Linux-OS-5.5.0.0 03
Run Code Online (Sandbox Code Playgroud)


rah*_*hul 16

像这样的东西对我有用,虽然我确信有更好的方法

echo "swp-RedHat-Linux-OS-5.5.0.0-03" | rev | sed 's/-/ /' | rev
swp-RedHat-Linux-OS-5.5.0.0 03
Run Code Online (Sandbox Code Playgroud)

  • 对于只对正则表达式有基本了解的人来说,这个答案似乎更平易近人。谁在乎需要多少次操作,这对于所有实际情况都是即时的。所以我会考虑一些任意规则的可读性,以使用尽可能少的操作。 (11认同)
  • @Psirus 我希望这不会打开一堆蠕虫,但使用较少操作的想法是展示一定程度的 * 掌握 * * 较小 * 操作。例如,@Thor 的回答显示了对 `bash` 参数扩展功能的赞赏,如果 OP 也使用 `bash`,该功能效果很好。在可读性(到非常冗长的程度)和使用正确的工具之间会有微妙的平衡,但通常情况下,使用正确的工具会占上风。 (6认同)