I want to replace some strings in files that contain $ signs with an other string that also contains $ signs plus the value from a bash variable. The file contains strings like the following.
$Rev: 12345 $ $Author: 12345 $
Lets say I have a bash variable called i
containing the string foo
. I now want to replace $Rev: 12345 $
with $Rev: $i $
. I tried using sed but since sed doesn't support non-greedy regex I switched to perl. Perl works fine when I don't use any bash variables.
# cat file
$Rev: 12345 $ $Author: 12345 $
# perl -p -i -e 's;\$Rev:.*?\$;\$Rev: test \$;g' file
# cat file
$Rev: test $ $Author: 12345 $
But no matter how I escape the $ signs in the command, I cannot get it to work with a bash variable.
# cat file
$Rev: 12345 $ $Author: 12345 $
# i="foo"
# echo $i
foo
# perl -p -i -e "s;\$Rev:.*?\$;\$Rev: $i \$;g" file
Final $ should be \$ or $name at -e line 1, within string
syntax error at -e line 1, near "s;$Rev:.*?$;$Rev: foo $;g"
Execution of -e aborted due to compilation errors.
# perl -p -i -e "s;\\$Rev:.*?\\$;\$Rev: $i \\$;g" file
# cat file
$Rev: foo $ $Author: foo $
Thanks for your help!
CodePudding user response:
It's better to use a Perl variable inside Perl, not let the shell expand its variable into Perl code.
perl -i~ -pe 's/^\$Rev:.*?\$/\$Rev: $i \$/g' -s -- -i="$i" file
You can then use single quotes around the code which makes it much easier to backslash stuff correctly.
The -s
tells Perl to accept -var=val
switches and set Perl variable $var
to val
before running the code.
CodePudding user response:
Try putting $i
outside the quotes entirely:
perl -pi -e 's;\$Rev:.*?\$;\$Rev: '$i' \$;g' file
# ^---------------------^ ^-----^
Or, you could export
the variable to sub-processes, and access it via the %ENV
hash in Perl:
export i="foo"
perl -pi -e 's;\$Rev:.*?\$;\$Rev: $ENV{i} \$;g' file