我运行几个替换命令作为 colorize script for maven 的核心。 sed
命令之一使用正则表达式,它在 shell 中作为 discussed here 工作。当前的(不工作的)实现可以在 here 中找到。
当我将命令的变体之一包含到脚本中时,会发生不同的行为:
变体 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, char 59: 's' 命令的 RHS 上的无效引用 \1
-i
(就地编辑选项)与 -re
组合在一起,产生了 -ire
(因此 -i
将 re
片段用作其 SUFFIX
参数,因此扩展了正则表达式模式未启用);将其更改为 -i -re
解决了该问题。
'
和双引号 "
的处理方式略有不同,尤其是在解释 $vars
时。例如:sudo 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'
无效。
您不需要实际捕获才能使其正常工作吗?即变体#2:
-r -e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \
(注:未经测试)
如果没有 -r
参数,反向引用(如 \1
)将不起作用,除非每个括号都使用 \
字符进行转义。
使用 -r
,除非括号未转义,否则参数反向引用(如 \1
)将不起作用。
对于未转义的括号,此错误很常见。逃离他们,然后再试一次。
例如:
/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n(.)/\1/g
应该在每个括号之前用反斜杠转义:
/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g
-r
,则不必转义括号。
如果未提供 -r
/--regexp-extended
选项,则必须对捕获括号进行转义。
您需要在 .
之后转义 /
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"
sed: -e expression #7, char 58: Invalid range end
。 @Denis 的回答有效。
不定期副业成功案例分享
-r
选项似乎是反向引用工作所必需的。例如,sed -e 's/([[:digit:]])/is a digit/'
有效,但sed -e 's/([[:digit:]])/\1 is a digit/
产生原始错误,而没有-r
到 sed。 注意: sed 的第一次调用搜索文字(<digit>)
并且 不是 捕获组。-ire
而不是使用-ri
。订单事项:-)-r, --regexp-extended
=use extended regular expressions in the script.
在大多数当前版本中,-E
和-r
都可以使用。扩展而不是基本。