我想将一个“模板”文件的输出管道到MySQL中,该文件具有像${dbName}这样的变量。替换这些实例并将输出转储到标准输出的命令行实用程序是什么?

输入文件被认为是安全的,但是可能存在错误的替换定义。执行替换应避免执行意外的代码执行。


当前回答

在地方perl编辑潜在的多个文件,与备份。

  perl -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/eg' \
    -i.orig \
    -p config/test/*

其他回答

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

鉴于最近的兴趣,我又在考虑这个问题,我认为我最初想到的工具是m4,用于autotools的宏处理器。所以不是我最初指定的变量,你会使用:

$echo 'I am a DBNAME' | m4 -DDBNAME="database name"

创建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

如果您愿意使用Perl,这就是我的建议。尽管可能有一些sed和/或AWK专家知道如何更容易地做到这一点。如果您有一个比dbName更复杂的映射可供替换,那么您可以很容易地扩展它,但是此时您也可以将它放入标准Perl脚本中。

perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql

一个简短的Perl脚本来做一些稍微复杂的事情(处理多个键):

#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;

如果你将上面的脚本命名为replace-script,那么它可以像下面这样使用:

replace-script < yourfile | mysql

file.tpl:

The following bash function should only replace ${var1} syntax and ignore 
other shell special chars such as `backticks` or $var2 or "double quotes". 
If I have missed anything - let me know.

script.sh:

template(){
    # usage: template file.tpl
    while read -r line ; do
            line=${line//\"/\\\"}
            line=${line//\`/\\\`}
            line=${line//\$/\\\$}
            line=${line//\\\${/\${}
            eval "echo \"$line\""; 
    done < ${1}
}

var1="*replaced*"
var2="*not replaced*"

template file.tpl > result.txt