我想替换(整个字符串)
$(TOPDIR)/$(OSSCHEMASDIRNAME)
与
/udir/makesh/$(OSSCHEMASDIRNAME)
<{3>} 中的
我试过
perl -pi.bak -e "s/\$\(TOPDIR\)\/\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\$\(OSSCHEMASDIRNAME\)/g " makefile
但是我得到了无法匹配的括号错误
答案 0 :(得分:2)
你必须“加倍”逃脱美元符号。像这样:
echo "\$(TOPDIR)/\$(OSSCHEMASDIRNAME)" | perl -p -e "s/\\$\(TOPDIR\)\/\\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\\$\(OSSCHEMASDIRNAME\)/g"
答案 1 :(得分:2)
首先,您不需要将/
用于正则表达式。他们只是规范的。你几乎可以使用任何东西。因此,您的代码可以变为(简化一些\
):
perl -pi.bak -e "s|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g " makefile
现在要实际解决您的问题,因为您使用的是"
而不是'
,shell会尝试找出$\
意味着什么然后替换为(推测)什么都没有。所以你真正想要的是:
perl -p -i.bak -e 's|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g' makefile
答案 2 :(得分:1)
如果对转义有疑问,您只需使用quotemeta
或\Q ... \E
。
perl -pe 's#\Q$(TOPDIR)\E(?=/\Q$(OSSCHEMASDIRNAME)\E)#/udir/makesh#;'
注意使用前瞻断言来节省我们在替换中重复尾随部分的麻烦。
quotemeta
解决方案类似于:
perl -pe 'BEGIN { $dir = quotemeta(q#$(TOPDIR)/$(OSSCHEMASDIRNAME)#); }
s#$dir#/udir/makesh/$(OSSCHEMASDIRNAME)#;'
当然,你不需要使用实际的单行。当shell引用引起麻烦时,最简单的选择就是为你的脚本编写一个小的源文件:
s#\Q$(TOPDIR)\E(?=/\Q$(OSSCHEMASDIRNAME)\E)#/udir/makesh#;
运行:
perl -p source.pl inputfile