Chris Pavey Asked: 2018-10-31 02:54:42 +0800 CST2018-10-31 02:54:42 +0800 CST 2018-10-31 02:54:42 +0800 CST 使用 sed 替换最后出现的字符 772 我正在尝试替换多行字符串变量中最后一次出现的字符。 我需要|用`. linux shell 4 个回答 Voted Stéphane Chazelas 2018-10-31T03:08:27+08:002018-10-31T03:08:27+08:00 .*您可以使用贪婪的事实: sed 's/\(.*\)|/\1`/' 或使用: sed 's/|\([^|]*\)$/`\1/' 如 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]} Best Answer Toby Speight 2018-10-31T03:01:25+08:002018-10-31T03:01:25+08:00 您可以通过管道rev,替换第一次出现,然后rev再次通过: rev | sed -e 's/|/`/' | rev 或者,在 pure 中sed,您希望替换| 后跟不包括|与`后跟相同序列的任何内容: sed -e 's/|\([^|]*\)$/`\1/' 我认为第一个更容易阅读和理解。 Kusalananda 2018-10-31T05:11:53+08:002018-10-31T05:11:53+08:00 $ printf '%s\n' "$str" abc|def ghi|jkl $ printf '%s\n' "${str%\|*}"'`'"${str##*\|}" abc|def ghi`jkl ${str%\|*}扩展为包含最后一个字符串|和删除后的所有内容的字符串。 ${str##*\|}扩展为带有最后一个字符串|和删除之前的所有内容的字符串。 上述两个参数替换的组合,中间有一个`,给出了结果字符串。 Eduardo Lucio 2022-08-17T17:36:47+08:002022-08-17T17:36:47+08:00 @StéphaneChazelas 以更“说教”的方式回答的一部分...... sed -z 's/\(.*\)<YOUR_ESCAPED_TARGET>/\1<YOUR_ESCAPED_REPLACE>/' 注意-zwhich 的使用允许<YOUR_ESCAPED_TARGET>和<YOUR_ESCAPED_REPLACE>有多行。 注意:可以在此处找到更完整的答案来解释如何<YOUR_ESCAPED_TARGET>以及如何进行转义。<YOUR_ESCAPED_REPLACE> 谢谢!?
.*
您可以使用贪婪的事实:或使用:
如 Toby 所示,要匹配
|
不包含|
直到行尾的内容,但该方法仅适用于单个字符替换。要使用 GNU 在多行字符串 shell 变量中替换它
sed
,您可以使用-z
将输入视为 NUL 分隔而不是换行分隔的选项:另一种方法是使用标准参数扩展运算符进行替换:
或者将这些
sed
命令翻译成等效的 shell:在
ksh93
:在
bash
(假设字符串不包含在当前语言环境中不形成有效字符的字节序列):在
zsh
:您可以通过管道
rev
,替换第一次出现,然后rev
再次通过:或者,在 pure 中
sed
,您希望替换|
后跟不包括|
与`
后跟相同序列的任何内容:我认为第一个更容易阅读和理解。
${str%\|*}
扩展为包含最后一个字符串|
和删除后的所有内容的字符串。${str##*\|}
扩展为带有最后一个字符串|
和删除之前的所有内容的字符串。上述两个参数替换的组合,中间有一个
`
,给出了结果字符串。@StéphaneChazelas 以更“说教”的方式回答的一部分......
注意
-z
which 的使用允许<YOUR_ESCAPED_TARGET>
和<YOUR_ESCAPED_REPLACE>
有多行。注意:可以在此处找到更完整的答案来解释如何
<YOUR_ESCAPED_TARGET>
以及如何进行转义。<YOUR_ESCAPED_REPLACE>
谢谢!?