使用 sed 替换最后一次出现的字符

Chr*_*vey 5 linux shell scripting sed

我正在尝试替换多行字符串变量中最后一次出现的字符。

我需要将最后|一个替换为`.

Sté*_*las 6

您可以使用贪婪的事实.*

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

或者使用:

sed 's/|\([^|]*\)$/`\1/'
Run Code Online (Sandbox Code Playgroud)

匹配 on|后跟不包含|til 行尾的内容,如 Toby 所示,但该方法仅适用于单个字符替换。

要使用 GNU 在多行字符串 shell 变量中替换它sed,您可以使用-z将输入视为 NUL 分隔而不是换行分隔的选项:

var=$(printf %s "$var" | sed -z '...')
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用标准参数扩展运算符进行替换:

case $var in
  (*'|'*) var=${var%'|'*}'`'${var##*'|'}
esac
Run Code Online (Sandbox Code Playgroud)

或者将这些sed命令翻译成它们的 shell 等效项:

ksh93

var=${var/@(*)'|'/\1'`'}
var=${var/%'|'*([^'|'])/'`'\1}
Run Code Online (Sandbox Code Playgroud)

bash(假设字符串不包含在当前语言环境中不形成有效字符的字节序列):

re='(.*)\|(.*)'
[[ $var =~ $re ]] && var=${BASH_REMATCH[1]}'`'${BASH_REMATCH[2]}
Run Code Online (Sandbox Code Playgroud)

zsh

set -o extendedglob
var=${var/(#b)(*)'|'/$match[1]'`'}

var=${var/%(#b)'|'([^'|']#)/'`'$match[1]}
Run Code Online (Sandbox Code Playgroud)


Tob*_*ght 2

您可以通过管道rev,替换第一次出现的位置,然后rev再次通过:

rev | sed -e 's/|/`/' | rev
Run Code Online (Sandbox Code Playgroud)

或者,在 pure 中sed,您想要替换| 后跟任何不包含|with的内容`,后跟相同的序列:

sed -e 's/|\([^|]*\)$/`\1/'
Run Code Online (Sandbox Code Playgroud)

我认为第一个更容易阅读和理解。

  • 如果您有 GNU sed(可能是在 Linux 上),您可以使用 `-z` 或 `--null-data` 将行分隔符设置为 NUL 字符,这样您的整个输入将被视为一行。 (3认同)