Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expand shell variables in a text file?

Consider a ASCII text file (lets say it contains code of a non-shell scripting language):

Text_File.msh:

spool on to '$LOG_FILE_PATH/logfile.log';
login 'username' 'password';
....

Now if this were a shell script I could run it as $ sh Text_File.msh and the shell would automatically expand the variables. What I want to do is have shell expand these variables and then create a new file as Text_File_expanded.msh as follows:

Text_File_expanded.msh:

spool on to '/expanded/path/of/the/log/file/../logfile.log';
login 'username' 'password';
....

Consider:

$ a=123
$ echo "$a"
123

So technically this should do the trick:

$ echo "`cat Text_File.msh`" > Text_File_expanded.msh

...but it doesn't work as expected and the output-file while is identical to the source.

So I am unsure how to achieve this.. My goal is make it easier to maintain the directory paths embedded within my non-shell scripts. These scripts cannot contain any UNIX code as it is not compiled by the UNIX shell.

like image 244
Kent Pawar Avatar asked Jan 21 '13 08:01

Kent Pawar


People also ask

How do you expand a variable in SED?

Just use double quotes instead of single quotes. You'll also need to use {} to delimit the number_line variable correctly and escape the \ , too.

What is $_ in shell script?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.


3 Answers

This question has been asked in another thread, and this is the best answer IMO:

export LOG_FILE_PATH=/expanded/path/of/the/log/file/../logfile.log cat Text_File.msh | envsubst > Text_File_expanded.msh 

if on Mac, install gettext first: brew install gettext

see: Forcing bash to expand variables in a string loaded from a file

like image 185
Dima Lituiev Avatar answered Oct 12 '22 23:10

Dima Lituiev


This solution is not elegant, but it works. Create a script call shell_expansion.sh:

echo 'cat <<END_OF_TEXT' >  temp.sh cat "$1"                 >> temp.sh echo 'END_OF_TEXT'       >> temp.sh bash temp.sh >> "$2" rm temp.sh 

You can then invoke this script as followed:

bash shell_expansion.sh Text_File.msh Text_File_expanded.msh 
like image 29
Hai Vu Avatar answered Oct 12 '22 23:10

Hai Vu


If you want it in one line (I'm not a bash expert so there may be caveats to this but it works everywhere I've tried it):

when test.txt contains

${line1}
${line2}

then:

>line1=fark
>line2=fork
>value=$(eval "echo \"$(cat test.txt)\"")
>echo "$value"
line1 says fark
line2 says fork

Obviously if you just want to print it you can take out the extra value=$() and echo "$value".

like image 20
ThirteenThirtySeven Avatar answered Oct 13 '22 00:10

ThirteenThirtySeven