我想将一个“模板”文件的输出管道到MySQL中,该文件具有像${dbName}这样的变量。替换这些实例并将输出转储到标准输出的命令行实用程序是什么?
输入文件被认为是安全的,但是可能存在错误的替换定义。执行替换应避免执行意外的代码执行。
我想将一个“模板”文件的输出管道到MySQL中,该文件具有像${dbName}这样的变量。替换这些实例并将输出转储到标准输出的命令行实用程序是什么?
输入文件被认为是安全的,但是可能存在错误的替换定义。执行替换应避免执行意外的代码执行。
当前回答
使用/bin/sh.创建一个设置变量的小shell脚本,然后使用shell本身解析模板。如下所示(编辑以正确处理换行):
文件template.txt:
the number is ${i}
the word is ${word}
文件script.sh:
#!/bin/sh
#Set variables
i=1
word="dog"
#Read in template one line at the time, and replace variables (more
#natural (and efficient) way, thanks to Jonathan Leffler).
while read line
do
eval echo "$line"
done < "./template.txt"
输出:
#sh script.sh
the number is 1
the word is dog
其他回答
鉴于最近的兴趣,我又在考虑这个问题,我认为我最初想到的工具是m4,用于autotools的宏处理器。所以不是我最初指定的变量,你会使用:
$echo 'I am a DBNAME' | m4 -DDBNAME="database name"
下面是一种让shell为您执行替换的方法,就像在双引号之间输入文件的内容一样。
以包含内容的template.txt为例:
The number is ${i}
The word is ${word}
下面的代码行将使shell插入template.txt的内容并将结果写入标准输出。
i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'
解释:
I和word作为环境变量传递给sh的执行。 Sh执行传入的字符串的内容。 相邻的字符串变成一个字符串,这个字符串就是: “echo”+“$(cat template.txt)”+ " ' 由于替换在"之间,"$(cat template.txt)"成为cat template.txt的输出。 因此sh -c执行的命令变成: echo“数字是${i}\n字是${word}”, 其中I和word是指定的环境变量。
创建rendertemplate.sh:
#!/usr/bin/env bash
eval "echo \"$(cat $1)\""
和template.tmpl:
Hello, ${WORLD}
Goodbye, ${CHEESE}
渲染模板:
$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl
Hello, Foo
Goodbye, Bar
template.txt
Variable 1 value: ${var1}
Variable 2 value: ${var2}
data.sh
#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"
parser.sh
#!/usr/bin/env bash
# args
declare file_data=$1
declare file_input=$2
declare file_output=$3
source $file_data
eval "echo \"$(< $file_input)\"" > $file_output
./parser.sh data.sh template.txt parsed_file.txt
parsed_file.txt
Variable 1 value: value 1
Variable 2 value: value 2
更新
下面是yottatsa关于类似问题的解决方案,它只替换像$VAR或${VAR}这样的变量,并且是一个简短的一行程序
i=32 word=foo envsubst < template.txt
当然,如果i和word在你的环境中,那么它只是
envsubst < template.txt
在我的Mac上,它看起来是作为gettext和MacGPG2的一部分安装的
旧的答案
这里是一个改进的解决方案从mogsie对类似的问题,我的解决方案不需要你的双引号,mogsie的做,但他是一个一行!
eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
这两种解决方案的强大之处在于,您只能获得几种正常情况下不会发生的shell扩展类型$((…)),'…',和$(…),虽然反斜杠在这里是一个转义字符,但您不必担心解析有bug,它可以很好地处理多行。