Depending on how this command is run, the string interpolation issues can be awful to predict. Is the double quoted string interpolated by sh
? Does the backslash in front of $
mean that it is escaped from sh
, but not from Perl interpolation? When I ran a test string in pastebin, it simply removed the $ENV{$1}
.
I'm sure there's a way to do it the hard way (this way), but an easy way is to just write the Perl code in a file instead, and run the file.
I would write your regexes like this, in a separate file, say foo.pl
:
s|\${([^}]+)}|$ENV{$1} // $&|eg;
s/\${([^}]+)}//g;
Using the logical defined-or operator //
is slightly prettier than using the ternary operator. We change delimiter on the substitution operator to facilitate that.
I removed unused e
modifier on second substitution.
You should note that all strings that match the regex ${....}
will be removed from the input by the second substitution. So the fact that you attempt to put them back with the first substitution with $&
is quite meaningless. Moreover using $&
carries a notable performance reduction. Assuming that is a mistake from your side, the code can be shortened to:
s/\${([^}]+)}/$ENV{$1}/g;
Note that now you can also skip the dangerous eval modifier /e
.
If you run it without warnings, which you do in your original code, you will not notice the undefined values in the %ENV
hash, it will just return the empty string -- i.e. remove undefined values.
This code can now be run by your other script without interpolation issues:
sh "perl -p foo.pl .env"
Just remove the -e
switch since you are no longer providing command line code.