Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using bash variable names as match replacement in perl regex substitution command line

I'm trying to replace substrings delimited by characters in a string by the values of their matching bash variables in shell.

So far, I've tried this without any success:

varone="noob"
vartwo="trivial"
echo "my {varone} and {vartwo} question" | perl -pe 's|(.*){(\w+)}(.*)|${1}'$(echo "${'${2}'}")'${3}|g'

But I get:

bash: ${'${2}'}: bad substitution

Any idea on how to do this? Thanks in advance!

like image 900
garys Avatar asked Feb 04 '26 08:02

garys


2 Answers

Don't generate Perl code from the shell! It isn't easy.

Instead of generating code, pass the values to the script. This answer shows a couple of ways you can pass values to a Perl one-liner. Exporting the variables you want to interpolate is the simplest here.

export varone="noob"
export vartwo="trivial"
echo "my {varone} and {vartwo} question" |
   perl -pe's/\{(\w+)\}/$ENV{$1}/g'

It also means you can interpolate other variables like PATH. If that's no good, you'll have to somehow check if the variable name is legal.

export varone="noob"
export vartwo="trivial"
echo "my {varone} and {vartwo} question" |
   perl -pe's/\{(varone|vartwo)\}/$ENV{$1}/g'
like image 134
ikegami Avatar answered Feb 05 '26 23:02

ikegami


Your main problem here is that you need to use export in order for your variables to be seen in your subprocesses (like the perl process).

export varone="noob"
export vartwo="trivial"
echo "my {varone} and {vartwo} question" | perl -pe '...'

You also need to know that shell variables are accessed inside a Perl program using the %ENV hash.

So your code can be simplified to:

export varone="noob"
export vartwo="trivial"
echo "my {varone} and {vartwo} question" | perl -pe 's|\{(\w+)}|$ENV{$1}|g'

You might consider adding an option to check for unknown variables.

export varone="noob"
export vartwo="trivial"
echo "my {varone} and {vartwo} question {varxxx}" | perl -pe 's|\{(\w+)}|$ENV{$1}//"UNKNOWN"|g'

But I'd recommend looking at a proper templating engine for this.

like image 34
Dave Cross Avatar answered Feb 05 '26 22:02

Dave Cross