bash - 在文本文件中,bash如何展开 shell 变量?

  显示原文与译文双语对照的内容
128 5

考虑ASCII文本文件( 假设它包含非shell脚本语言的代码):

Text_File.msh:


spool on to '$LOG_FILE_PATH/logfile.log';


login 'username' 'password';


....



现在如果是 shell script,我可以将它作为 $ sh Text_File.msh 运行,shell 会自动扩展变量。 我想要做的是让 shell 扩展这些变量,然后按如下方式创建一个新的文件:

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脚本中的目录路径变得更加容易。 但是,这些脚本不能包含任何UNIX代码,因为它不是由UNIX代码编译。

时间: 原作者:

54 5

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



原作者:
89 1

在另一个线程中询问了这个问题,这是IMO的最佳答案:


export LOG_FILE_PATH=/expanded/path/of/the/log/file/../logfile.log'


cat Text_File.msh | envsubst> Text_File_expanded.msh



如果在Mac上,首先安装 gettext: brew install gettext

see 强制bash在从文件加载的字符串中展开变量。

原作者:
121 1

如果Perl解决方案对你来说是可行的:

示例 file:


$ 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';



原作者:
83 2

如果你希望在一行中使用( 我不是一个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"

原作者:
90 0

上述答案的一个限制是,它们都要求将变量导出到环境中。 这里是我所提到的,将允许变量在当前 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 在 命令行 上命名的文件中被替换。 我相信它可以改进,但这对我来说是有效的。

感谢以前对他们的想法的回答 !

原作者:
107 1

如果你要翻译的变量已知且数量有限,你可以自己进行翻译:


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



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

原作者:
115 1

这个解决方案允许你在输出文件中保持相同的格式

在脚本中复制并粘贴以下行


cat $1 | while read line


do


 eval $line


 echo $line


 eval echo $line


done | uniq | grep -v '$'



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

75 2

创建一个具有以下内容的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


....



...