Perl:Bareword找到了运营商期望的

时间:2018-12-05 08:19:30

标签: perl sh bareword

我正在尝试使用perl替换这样的字符串:

perl -pe "s/FlDigVal/$DIGN/" Header.xml > $DDIRP/$FNAME.xml

如果DIGN=+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=出现以下语法错误:

Having no space between pattern and following word is deprecated at -e line 1.
Bareword found where operator expected at -e line 1, near "s/FlDigVal/+q4T/h"
Having no space between pattern and following word is deprecated at -e line 1.
syntax error at -e line 1, near "s/FlDigVal/+q4T/h"
Execution of -e aborted due to compilation errors.

我想这与/h在变量DIGN中有关。有办法逃脱那些保留字吗?

2 个答案:

答案 0 :(得分:3)

不要使用shell变量,它们只是非卫生的宏。将变量导出到Perl的环境:

DIGN=$DIGN perl -pe 's/FlDigVal/$ENV{DIGN}/'

请注意单引号:我们不希望shell更改Perl命令。

或将值作为参数传递:

perl -pe 'BEGIN { $replace = shift } s/FlDigVal/$replace/' "$DIGN" Header.xml

尽管如此,您似乎正在使用正则表达式编辑XML文档。这是一种痛苦的方式,有XML::LibXML之类的库可以正确处理XML。例如。如果DIGN包含&<会发生什么?

答案 1 :(得分:1)

问题不是保留字,而是/

如果DIGN包含+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=,则您的命令将以下代码传递给perl:

s/FlDigVal/+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=/

这里s/FlDigVal/+q4T/解析为替换命令,但其余都是垃圾。

解决方案是不要让Shell将变量插值到代码中。相反,您可以通过环境传递字符串:

DIGN="$DIGN" perl -pe 's/FlDigVal/$ENV{DIGN}/' Header.xml

(如果已经导出DIGN,则不需要DIGN="$DIGN"部分。)

在这里,我们使用单引号(没有外壳插值),然后让perl从环境中获取一个值。