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

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

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

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

答案1

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

sed 's/\(.*\)|/\1`/'

或者使用:

sed 's/|\([^|]*\)$/`\1/'

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

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

var=$(printf %s "$var" | sed -z '...')

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

case $var in
  (*'|'*) var=${var%'|'*}'`'${var##*'|'}
esac

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

ksh93

var=${var/@(*)'|'/\1'`'}
var=${var/%'|'*([^'|'])/'`'\1}

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

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

zsh

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

var=${var/%(#b)'|'([^'|']#)/'`'$match[1]}

答案2

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

rev | sed -e 's/|/`/' | rev

或者,在 pure 中sed,您想要替换| 后面跟不包括的任何内容|后面`跟着相同的顺序:

sed -e 's/|\([^|]*\)$/`\1/'

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

答案3

$ printf '%s\n' "$str"
abc|def
ghi|jkl
$ printf '%s\n' "${str%\|*}"'`'"${str##*\|}"
abc|def
ghi`jkl
  • ${str%\|*}|扩展为带有最后一个以及删除后的所有内容的字符串。
  • ${str##*\|}|扩展为包含最后一个和删除之前的所有内容的字符串。

上述两个参数替换的组合(`中间有一个)给出了结果字符串。

答案4

@Stéphane Chazelas 以更“说教”的方式回答的一部分......

sed -z 's/\(.*\)<YOUR_ESCAPED_TARGET>/\1<YOUR_ESCAPED_REPLACE>/'

请注意,它的使用-z允许<YOUR_ESCAPED_TARGET><YOUR_ESCAPED_REPLACE>具有多行。

笔记:可以找到更完整的答案,解释如何转义<YOUR_ESCAPED_TARGET>以及如何转义<YOUR_ESCAPED_REPLACE>这里

谢谢!

相关内容