如何在文本文件中扩展shellvariables?

考虑一个ASCII文本文件(可以说它包含非shell脚本语言的代码):

Text_File.msh:

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

现在,如果这是一个shell脚本,我可以运行它为$ sh Text_File.msh和shell会自动扩大variables。 我想要做的是有壳扩大这些variables,然后创build一个新文件为Text_File_expanded.msh如下:

Text_File_expanded.msh:

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

考虑:

 $ a=123 $ echo "$a" 123 

所以在技术上这应该做的伎俩:

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

…但不能按预期工作,输出文件与源文件完全相同。

所以我不确定如何做到这一点..我的目标是维护非shell脚本中embedded的目录path。 这些脚本不能包含任何UNIX代码,因为它不是由UNIX shell编译的。

这个解决方案不是很高雅,但是可以工作。 创建一个脚本调用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 

然后你可以按如下方式调用这个脚本:

 bash shell_expansion.sh Text_File.msh Text_File_expanded.msh 

这个问题已经在另一个线程中提出,这是IMO的最佳答案:

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

如果在Mac上,先安装gettextbrew install gettext

请参阅: 强制bash扩展从文件加载的字符串中的变量

如果Perl解决方案适合您:

示例文件:

 $ cat file.sh spool on to '$HOME/logfile.log'; login 'username' 'password'; 

解:

 $ perl -pe 's/\$(\w+)/$ENV{$1}/g' file.sh spool on to '/home/user/logfile.log'; login 'username' 'password'; 

上述答案的一个局限是它们都需要将变量导出到环境中。 这是我想到的,将允许变量是当前shell脚本本地:

 #!/bin/sh FOO=bar; FILE=`mktemp`; # Let the shell create a temporary file trap 'rm -f $FILE' 0 1 2 3 15; # Clean up the temporary file ( echo 'cat <<END_OF_TEXT' cat "$@" echo 'END_OF_TEXT' ) > $FILE . $FILE 

上面的例子允许在命令行中命名的文件中替换变量$FOO 。 我相信它可以改善,但这对我来说目前为止。

感谢他们的想法以前的答案!

如果你想在一行(我不是一个bash的专家,所以可能有这样的警告,但它在我试过的地方工作):

当test.txt包含

 ${line1} ${line2} 

然后:

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

显然,如果你只是想打印它,你可以拿出额外的value=$()echo "$value"

如果你想翻译的变量是已知的,并且数量有限,你可以自己做翻译:

 sed "s/\$LOG_FILE_PATH/$LOG_FILE_PATH/g" input > output 

而且假设变量本身已经是已知的

用以下内容创建一个ascii文件test.txt:

 Try to replace this ${myTestVariable1} bla bla .... 

现在创建一个包含变量名称的文件“sub.sed”,例如

 's,${myTestVariable1},'"${myTestVariable1}"',g; s,${myTestVariable2},'"${myTestVariable2}"',g; s,${myTestVariable3},'"${myTestVariable3}"',g; s,${myTestVariable4},'"${myTestVariable4}"',g' 

打开终端移动到包含test.txt和sub.sed的文件夹。
定义要替换的变量的值

 myTestVariable1=SomeNewText 

现在调用sed来替换该变量

 sed "$(eval echo $(cat sub.sed))" test.txt > test2.txt 

输出将是

 $cat test2.txt Try to replace this SomeNewText bla bla .... 

该解决方案允许您在输出文件中保持相同的格式

将以下行复制并粘贴到脚本中

 cat $1 | while read line do eval $line echo $line eval echo $line done | uniq | grep -v '\$' 

这将读取作为参数逐行传递的文件,然后处理尝试打印两行: – 一次没有替换 – 一次替换的变量。 然后删除重复的行,然后删除包含可见变量的行($)