为什么带有 \\$\{ 的正则表达式可以与egrep一起使用,但不能与sed一起使用?

为什么带有 \\$\{ 的正则表达式可以与egrep一起使用,但不能与sed一起使用?

给定这样的文本

./RFF_09 -f${FILE} -c${COND}

在文件内,此egrep命令将正确匹配:

egrep './RFF(.*) (.*)-c\\$\{COND\}' file

但这个 sed 命令不会

sed -n "s:'./RFF(.*) (.*)-c\\$\{COND\}':./RFF$1 $2-cRFF$1:gp"

它将失败sed: -e expression #1, char 38: invalid content of \{\}。我也尝试过

sed -n "s:'./RFF(.*) (.*)-c\\$\{COND\}':DUMMY:gp" file
sed -n s:'./RFF(.*) (.*)-c\\$\{COND\}':DUMMY:gp file

得到相同的结果。

sed -n "s:'./RFF(.*) (.*)-c\\$\\{COND\\}':DUMMY:gp" file

不会给我错误消息,但不会匹配。

我究竟做错了什么?或者更好:如何按照原始命令的建议替换文本?我使用的是相当旧版本的 sed (4.1.2) 和 egrep (2.5.1),因此即使您无法使用较新版本重现错误,也可以使用解决方法。

答案1

如果你使用egrep 意味着 grep 具有扩展的正则表达式语法,因此为了能够将您的模式传输到 sed 中,您必须添加参数-r(--regexp-extended)-E在某些版本中。

关于你的表达你有额外的\所以c即使使用egrep它不匹配

\1另外,你最好使用$1反向匹配。

所以最终命令可能是:

sed -rn 's:\./(RFF.*)( .* -c)\$\{COND\}:./\1\2\1:gp'

或者

sed -rn 's:(\./(RFF\S*) \S* -c)\$\{COND\}:\1\2:gp'

答案2

在你原来的陈述中,问题是你混合了语法和字面意思引号:双引号内的单引号将按字面意思匹配。您需要简单地删除它们或混合引号(不是嵌套它们)。未经测试的示例:

sed 's/foo/{bar}/'
sed "s/foo/"'{bar}'"/"

有许多正则表达式的风格,并且它们都支持不同的语法。在仅使用单引号的尝试中,问题是正则表达式风格:sed用于\{N\}匹配计数,因此N需要是整数。您会想改用{COND}.

(确实,现在使用正则表达式来解决问题意味着您已经问题。在 shell 代码中执行几乎任何复杂的操作都意味着您会遇到 N 个问题,N 至少与行数一样大。)

相关内容