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代码编译。

时间:原作者:0个回答

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
....
原作者:
...