1

我想替换(整个字符串)

    $(TOPDIR)/$(OSSCHEMASDIRNAME)

    /udir/makesh/$(OSSCHEMASDIRNAME)

生成文件中

我试过了

     perl -pi.bak -e "s/\$\(TOPDIR\)\/\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\$\(OSSCHEMASDIRNAME\)/g " makefile

但我得到了无与伦比的括号错误

4

3 回答 3

2

您必须“加倍”转义美元符号。像这样:

echo "\$(TOPDIR)/\$(OSSCHEMASDIRNAME)" | perl -p -e "s/\\$\(TOPDIR\)\/\\$\(OSSCHEMASDIRNAME\)/\/udir\/makesh\/\\$\(OSSCHEMASDIRNAME\)/g"
于 2012-05-14T09:16:28.857 回答
2

首先,您不需要使用/正则表达式。他们只是规范的。你几乎可以使用任何东西。因此,您的代码可以变成(简化一些\):

perl -pi.bak -e "s|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g " makefile

现在要实际解决您的问题,因为您使用的是"代替',所以外壳会尝试找出什么$\意思,然后将其替换为(大概)什么都没有。所以你真正想要的是:

perl -p -i.bak -e 's|\$\(TOPDIR\)/\$\(OSSCHEMASDIRNAME\)|/udir/makesh/\$\(OSSCHEMASDIRNAME\)|g' makefile
于 2012-05-14T09:18:23.660 回答
1

当对转义有疑问时,您可以简单地使用quotemetaor \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
于 2012-05-14T11:31:01.530 回答