Dan*_*ane 137 bash command-line text-processing templating
我想将"模板"文件的输出传递给MySQL,该文件包含${dbName}散布的变量.什么是命令行实用程序来替换这些实例并将输出转储到标准输出?
use*_*ser 165
塞德!
给出template.txt:
The number is ${i}
The word is ${word}
我们只需要说:
sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.txt
Run Code Online (Sandbox Code Playgroud)
感谢Jonathan Leffler提示将多个-e参数传递给同一个sed调用.
plo*_*ckc 154
以下是来自yottatsa的类似问题的解决方案,该问题仅替换$ VAR或$ {VAR}等变量,并且是一个简短的单行
i=32 word=foo envsubst < template.txt
Run Code Online (Sandbox Code Playgroud)
当然,如果我和你的话语在你的环境中,那么它就是
envsubst < template.txt
Run Code Online (Sandbox Code Playgroud)
在我的Mac上,它看起来像是作为gettext和MacGPG2的一部分安装的
这是对mogsie在类似问题上的解决方案的改进,我的解决方案并不要求你使用双引号,mogsie's,但他是一个单行!
eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null
Run Code Online (Sandbox Code Playgroud)
这两个解决方案的优势在于你只能得到几种类型的shell扩展,这些扩展通常不会出现$((...)),`...`和$(...),尽管反斜杠是一个转义字符在这里,但你不必担心解析有一个错误,它做多行就好了.
gnu*_*nud 44
使用/bin/sh.创建一个设置变量的小shell脚本,然后使用shell本身解析模板.像这样(编辑以正确处理换行):
the number is ${i}
the word is ${word}
Run Code Online (Sandbox Code Playgroud)
#!/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"
Run Code Online (Sandbox Code Playgroud)
#sh script.sh
the number is 1
the word is dog
Run Code Online (Sandbox Code Playgroud)
Dan*_*ane 20
鉴于最近的兴趣,我再次考虑这个问题,我认为我最初想到的工具是m4autotools的宏处理器.因此,不是我最初指定的变量,而是使用:
$echo 'I am a DBNAME' | m4 -DDBNAME="database name"
Run Code Online (Sandbox Code Playgroud)
小智 12
template.txt
Variable 1 value: ${var1}
Variable 2 value: ${var2}
Run Code Online (Sandbox Code Playgroud)
data.sh
#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
./parser.sh data.sh template.txt parsed_file.txt
parsed_file.txt
Variable 1 value: value 1
Variable 2 value: value 2
Run Code Online (Sandbox Code Playgroud)
小智 10
这是我基于前一个答案的perl解决方案,替换环境变量:
perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"missing variable $1")/eg' < infile > outfile
Run Code Online (Sandbox Code Playgroud)
mkl*_*nt0 10
这是一个强大的Bash功能 - 尽管使用eval- 应该是安全的使用.
${varName}输入文本中的所有变量引用都基于调用shell的变量进行扩展.
没有其他东西被扩展:既没有包含{...}(例如$varName)名称的变量引用,也没有包含命令替换($(...)和遗留语法`...`),也没有算术替换($((...))和遗留语法$[...]).
把a $当作文字来对待\它吧.例如:\${HOME}
请注意,输入仅通过stdin接受.
例:
$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)
Run Code Online (Sandbox Code Playgroud)
功能源代码:
expandVarsStrict(){
local line lineEscaped
while IFS= read -r line || [[ -n $line ]]; do # the `||` clause ensures that the last line is read even if it doesn't end with \n
# Escape ALL chars. that could trigger an expansion..
IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([$' '\1\2\3\4')
# ... then selectively reenable ${ references
lineEscaped=${lineEscaped//$'\4'{/\${}
# Finally, escape embedded double quotes to preserve them.
lineEscaped=${lineEscaped//\"/\\\"}
eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
done
}
Run Code Online (Sandbox Code Playgroud)
该函数假定没有0x1,0x2,0x3,和0x4控制字符存在于输入,因为那些字符.在内部使用 - 因为函数处理文本,这应该是一个安全的假设.
创建rendertemplate.sh:
#!/usr/bin/env bash
eval "echo \"$(cat $1)\""
Run Code Online (Sandbox Code Playgroud)
而且template.tmpl:
Hello, ${WORLD}
Goodbye, ${CHEESE}
Run Code Online (Sandbox Code Playgroud)
渲染模板:
$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl
Hello, Foo
Goodbye, Bar
Run Code Online (Sandbox Code Playgroud)
如果您愿意使用Perl,那将是我的建议.虽然可能有一些sed和/或AWK专家可能知道如何更容易地做到这一点.如果您有一个更复杂的映射,而不仅仅是dbName用于替换,那么您可以非常轻松地扩展它,但是您也可以将其放入标准的Perl脚本中.
perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql
Run Code Online (Sandbox Code Playgroud)
一个简短的Perl脚本,可以做一些稍微复杂的事情(处理多个键):
#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;
Run Code Online (Sandbox Code Playgroud)
如果将上述脚本命名为replace-script,则可以按如下方式使用它:
replace-script < yourfile | mysql
Run Code Online (Sandbox Code Playgroud)
我建议使用类似Sigil 的东西:https : //github.com/gliderlabs/sigil
它被编译为单个二进制文件,因此在系统上安装非常容易。
然后你可以做一个简单的单行如下:
cat my-file.conf.template | sigil -p $(env) > my-file.conf
Run Code Online (Sandbox Code Playgroud)
这比eval使用正则表达式或sed
这是一种让 shell 为您进行替换的方法,就好像文件的内容是在双引号之间键入的。
使用带有内容的 template.txt 示例:
The number is ${i}
The word is ${word}
Run Code Online (Sandbox Code Playgroud)
以下行将导致 shell 插入 template.txt 的内容并将结果写入标准输出。
i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'
Run Code Online (Sandbox Code Playgroud)
解释:
i并word作为环境变量传递给sh.sh 执行传递给它的字符串的内容。echo "' + " $(cat template.txt)" + ' "'",“ $(cat template.txt)”成为 的输出cat template.txt。sh -c变为:
echo "The number is ${i}\nThe word is ${word}",i和word是指定的环境变量。| 归档时间: |
|
| 查看次数: |
125510 次 |
| 最近记录: |