1

我正在尝试使用正则表达式搜索/替换来$foo用大括号(例如;)封装变量(例如;${foo})。我想出了以下正则表达式,但它没有按预期工作:

s/"\([^"]*\)\$\([a-zA-Z0-9:]*\)\([^"]*\)"/"\1\${\2}\3"/g

但是,我对这种模式有一些问题。每个引用的字符串只会执行一种模式。这没关系,因为我可以在文件上多次运行表达式,但它不处理已经封装在大括号中的变量。它只是在他们身上放了第二套牙套。

我现在的想法是\2去掉大括号,但我认为这不会起作用,因为模式仍然会匹配,并且每个引用的字符串只会执行 1 次替换。我查看了反向引用表达式文档,但无法确定更好的方法。

4

2 回答 2

3

尝试以下操作:

sed -e ':loop' -e 's/"\([^"]*\)\$\([a-zA-Z0-9:]\{1,\}\)\([^"]*\)"/"\1\${\2}\3"/' -e 't loop'

这会将搜索/替换放入一个循环中,以便它将在每一行上重复尝试替换,直到无法进行更多替换。

这是有效的,因为当前正在处理的行仅在没有更多命令要运行时打印,:loop创建一个名为 的标签loop,并且只有在成功替换时才t loop将执行返回到该标签。loop

正如 potong 在评论中提到的,这可能会在带有多个引号的行上产生一些奇怪的行为,这是一种在这些情况下应该可以正常工作的替代方案:

sed -e ':loop' -e 's/^\([^"]*\("[^"]*"[^"]*\)*\)"\([^"]*\)\$\([a-zA-Z0-9:]\{1,\}\)\([^"]*\)"/\1"\3\${\4}\5"/' -e 't loop'
于 2012-10-01T23:07:47.263 回答
1

这可能对您有用(GNU sed):

echo 'a "$a" b $b "b $b b $b" $c c $c "$c c $c"' | 
sed 's/"\([^"]*\)"/"\n\1\n"/g;:a;s/\n\n//;ta;s/\n\$\([a-zA-Z0-9:]\+\)/${\1\}\n/;ta;s/\n\(.\)/\1\n/;ta'
a "${a}" b $b "b ${b} b ${b}" $c c $c "${c} c ${c}"
于 2012-10-02T08:58:12.270 回答