我正在尝试用正则表达式搜索/替换来封装变量(例如; $foo
)和大括号(例如; ${foo}
)。我提出了以下正则表达式,但它没有按预期工作:
s/"\([^"]*\)\$\([a-zA-Z0-9:]*\)\([^"]*\)"/"\1\${\2}\3"/g
但是,我对这种模式有一些问题。每个引用的字符串只会执行一个模式。这没关系,因为我可以在文件上多次运行表达式,但它不处理已经封装在大括号中的变量。它只是在它们上面放了第二组括号。
我现在的想法是剥离\2
大括号,但我认为这不会起作用,因为模式仍然匹配,并且每个引用的字符串只会执行1次替换。我查看了反向引用表达式文档,但我无法确定更好的方法。
答案 0 :(得分: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'
答案 1 :(得分: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}"