Perl: Bareword found where operator expected at

2.2k Views Asked by At

I am trying to use perl to replace a string like so:

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

If DIGN=+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA= i get the following syntax error:

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.

I guess this is related to /hbeing in variable DIGN. Is there a way to escape those reserved words?

2

There are 2 best solutions below

4
On BEST ANSWER

Don't use shell variables, which are just non-hygienic macros. Export the variable to Perl's environment:

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

Note the single quotes: we don't want the shell to change the Perl commands.

or pass the value as an argument:

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

Nevertheless, you seem to be editing an XML document with regular expressions. It's a painful way, there are libraries like XML::LibXML that handle XML correctly. E.g. what would happen if DIGN contained & or <?

4
On

The problem is not with reserved words but /.

If DIGN contains +q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=, your command passes the following code to perl:

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

Here s/FlDigVal/+q4T/ parses as a substitution command, but the rest is garbage.

The solution is to not let the shell interpolate variables into code. Instead you can pass strings via the environment:

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

(If DIGN is already exported, you don't need the DIGN="$DIGN" part.)

Here we use single quotes (no shell interpolation) and let perl grab a value from the environment.