Variable substitution in Perl with Perl special characters

Viewed 276

I would like to substitute a substring that contains an @ character with Perl as in the following sed command:

substitution='newusername@anotherwebsite.com'
sed 's/oldusername@website.com/'"${substitution}"'/g' <<< "The current e-mail address is oldusername@website.com"

At present wherever I use Perl instead of sed or awk I first replace \ with \\, / with \/, $ with \$ and @ with \@; e.g.

substitution='newusername@anotherwebsite.com'
substitution="${substitution//\\/\\\\}"
substitution="${substitution//\//\\/}"
substitution="${substitution//$/\\$}"
substitution="${substitution//@/\\@}"
perl -pe 's/oldusername\@website.com/'"${substitution}"'/g' <<< "The current e-mail address is oldusername@website.com"

I have read about using single quotation marks (as below based on sed/ perl with special characters (@)) but I was wondering if there is any other way to do this with forward slashes?

substitution='newusername@anotherwebsite.com'
perl -pe "s'oldusername@website.com'"${substitution}"'g" <<< "The current e-mail address is oldusername@website.com"

Also, are there special characters in Perl aside from $, @ and % (and why is there no need to escape %)?

1 Answers

The cleanest way is to pass the values to Perl, as it can handle variables in substitution patterns and replacements correctly. Use single quotes so the shell's variable expansion doesn't interfere. You can use the -s option (explained in perlrun).

#!/bin/bash
pattern=oldusername@website.com
substitution=newusername@anotherwebsite.com
perl -spe 's/\Q$pat/$sub/g' -- -pat="$pattern" -sub="$substitution" <<< "The current e-mail address is oldusername@website.com"

or propagate the values to Perl via the environment.

pattern=oldusername@website.com
substitution=newusername@anotherwebsite.com
pat=$pattern sub=$substitution perl -pe 's/\Q$ENV{pat}/$ENV{sub}/g' <<< "The current e-mail address is oldusername@website.com"

Note that you need to assign the values before calling Perl or you need to export them in order to propagate them into the environment.

The \Q applies quotemeta to the pattern, i.e. it escapes all the special characters so that they are interpreted literally.

There's no need to backslash % as hashes aren't interpolated in double quotes or regexes.

Related