sed 错误:“'s' 命令的 RHS 上的引用 \1 无效”

sed error: "invalid reference \1 on `s' command's RHS"

提问人:JJD 提问时间:5/20/2013 最后编辑:CommunityJJD 更新时间:7/14/2021 访问量:128003

问:

我运行了几个替换命令作为 maven 着色脚本的核心。 其中一个命令使用正则表达式,该表达式在 shell 中起作用,如此处所述。当前(不起作用)的实现可以在这里找到。sed

当我将命令的变体之一包含在脚本中时,会发生不同的行为:

变式1:

$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g"

改编自剧本:

-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \

错误:shell 输出的信息与我键入 .奇怪!?$ sed


变式2:

$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g"

改编自剧本:

-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \

错误:

sed:-e 表达式 #7,字符 59:对 's' 命令的 RHS 的引用 \1 无效

正则表达式 SED 替换

评论

16赞 Janaka Bandara 3/18/2017
就我而言,我将 (就地编辑选项) 与 组合在一起,导致 (因此将片段用作其参数,因此未启用扩展正则表达式模式);更改它以修复该问题。-i-re-ire-ireSUFFIX-i -re
0赞 not2qubit 1/2/2018
还要注意的是,单引号和双引号的处理方式略有不同,尤其是在解释 .例如:有效,但是:无效。'"$varssudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'

答:

103赞 Denis de Bernardy 5/20/2013 #1

难道你不需要实际捕获它就可以工作吗?即对于变体 #2:

-r -e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \

(注:未经测试)

如果没有参数,除非每个括号都用字符转义,否则反向引用(如)将不起作用。-r\1\

使用 ,参数反向引用(如)将不起作用,除非括号未转义。-r\1

评论

55赞 Andrew Falanga 3/24/2016
sed 选项似乎是反向引用工作所必需的。例如,有效,但产生原始错误而没有 sed。 注意:sed 的第一次调用会搜索文本,而不是捕获组。-rsed -e 's/([[:digit:]])/is a digit/'sed -e 's/([[:digit:]])/\1 is a digit/-r(<digit>)
0赞 miroxlav 9/3/2017
答案下面的评论实际上是一个答案。也许你可以编辑你的答案来反映它。
0赞 sanmai 2/8/2018
@AndrewFalanga你应该把你的评论作为答案
5赞 m3nda 6/10/2018
没关系,我的错误是使用而不是使用.订单很重要:-)-ire-ri
1赞 sastorsl 5/12/2022
-r, --regexp-extended = use extended regular expressions in the script.在大多数当前版本中,两者都可以使用。扩展而不是基本。-E-r
7赞 slackmart 5/20/2013 #2

你需要在/.

sed -e "s/\([a-zA-Z0-9.\/\\ :-]\+\)/\1/g"

或者,如果您不想担心逃跑,请使用|

sed -e "s|\([a-zA-Z0-9./\\ :-]\+\)|\1|g"

编辑:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"

评论

0赞 JJD 5/20/2013
听起来很合理。但它在脚本的上下文中不起作用。
0赞 JJD 5/20/2013
不好意思。编辑引发错误:。@Denis的答案有效。sed: -e expression #7, char 58: Invalid range end
2赞 slackmart 5/20/2013
好的,那么 +1 表示@Denis的答案
62赞 e18r 1/19/2016 #3

此错误对于未转义的括号很常见。逃离它们,然后再试一次。


例如:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n(.)/\1/g

应在每个括号前使用反斜杠转义:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g

评论

10赞 qräbnö 1/13/2018
注意,如果你使用,你不必转义括号。-r
35赞 OrangeDog 3/6/2019 #4

如果未提供 / 选项,则必须对捕获括号进行转义。-r--regexp-extended