我正在尝试替换多行字符串变量中最后一次出现的字符。
我需要将最后一个替换|
为`
.
答案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>
这里。
谢谢!