考虑一个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上,先安装gettext
: brew 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 '\$'
这将读取作为参数逐行传递的文件,然后处理尝试打印两行: – 一次没有替换 – 一次替换的变量。 然后删除重复的行,然后删除包含可见变量的行($)