Ken*_*war 15 unix bash shell ksh solaris
考虑一个ASCII文本文件(假设它包含非shell脚本语言的代码):
Text_File.msh:
spool on to '$LOG_FILE_PATH/logfile.log';
login 'username' 'password';
....
Run Code Online (Sandbox Code Playgroud)
现在,如果这是一个shell脚本,我可以运行它,$ sh Text_File.mshshell将自动扩展变量.我想要做的是让shell扩展这些变量,然后创建一个新文件Text_File_expanded.msh,如下所示:
Text_File_expanded.msh:
spool on to '/expanded/path/of/the/log/file/../logfile.log';
login 'username' 'password';
....
Run Code Online (Sandbox Code Playgroud)
考虑:
$ a=123
$ echo "$a"
123
Run Code Online (Sandbox Code Playgroud)
从技术上讲,这应该可以解决问题:
$ echo "`cat Text_File.msh`" > Text_File_expanded.msh
Run Code Online (Sandbox Code Playgroud)
...但它不能按预期工作,输出文件虽然与源相同.
所以我不确定如何实现这一点.我的目标是让我更容易维护嵌入在我的非shell脚本中的目录路径.这些脚本不能包含任何UNIX代码,因为它不是由UNIX shell编译的.
Dim*_*iev 27
这个问题已在另一个帖子中提出,这是IMO的最佳答案:
export LOG_FILE_PATH=/expanded/path/of/the/log/file/../logfile.log
cat Text_File.msh | envsubst > Text_File_expanded.msh
Run Code Online (Sandbox Code Playgroud)
如果在Mac上,请先安装gettext:brew install gettext
这个解决方案不优雅,但它有效.创建一个脚本调用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
Run Code Online (Sandbox Code Playgroud)
然后,您可以调用此脚本,如下所示:
bash shell_expansion.sh Text_File.msh Text_File_expanded.msh
Run Code Online (Sandbox Code Playgroud)
如果Perl解决方案适合您:
样本文件:
$ cat file.sh
spool on to '$HOME/logfile.log';
login 'username' 'password';
Run Code Online (Sandbox Code Playgroud)
解:
$ perl -pe 's/\$(\w+)/$ENV{$1}/g' file.sh
spool on to '/home/user/logfile.log';
login 'username' 'password';
Run Code Online (Sandbox Code Playgroud)
上述答案的一个限制是它们都需要将变量导出到环境中.以下是我提出的允许变量在当前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
Run Code Online (Sandbox Code Playgroud)
上面的示例允许$FOO在命令行上命名的文件中替换变量.我相信它可以改进,但到目前为止这对我有用.
感谢他们以前的想法的答案!
小智 8
如果你想要它在一行(我不是一个bash专家所以可能有一些警告,但它适用于我尝试过的所有地方):
当test.txt包含时
${line1}
${line2}
Run Code Online (Sandbox Code Playgroud)
然后:
>line1=fark
>line2=fork
>value=$(eval "echo \"$(cat test.txt)\"")
>echo "$value"
line1 says fark
line2 says fork
Run Code Online (Sandbox Code Playgroud)
显然,如果你只想打印它,你可以拿出额外的value=$()和echo "$value".