我有一个带有占位符字符串的骨架文本文件:
blah blah blah blah $PLACEHOLDER_1$ blah $PLACEHOLDER_2$
等等.占位符的特定"形式"并不重要 - 我可以将它们更改为最适合特定实现的任何内容.
我有一个bash脚本,我知道占位符的值,我需要生成一个新文件,占位符替换为值.
#! /bin/sh PLACEHOLDER_1 = 'string 1' PLACEHOLDER_2 = 'multiline string 2' # TODO: Generate file output.txt from file output.template # using placeholders above.
我可以用sed多次通过,但这并不好玩.我不希望使用Perl.我想只使用textutils和bash本身.
在一次传球中做我想做的最好的方法是什么?
这是一种没有sed的方法:
首先,稍微修改一下模板文件,其中占位符是bash变量:
blah blah blah blah $PLACEHOLDER_1 blah $PLACEHOLDER_2
和剧本:
#! /bin/sh templatefile=output.template outputfile=output.txt PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline string 2' # DONE: Generate file output.txt from file output.template # using placeholders above. echo "$(eval "echo \"$(cat $templatefile)\"")" > $outputfile
这是一个演示脚本中包含的模板的版本,但有一个扭曲.它还演示了默认值,也可以在模板文件版本中使用,还可以在模板中进行数学运算:
#! /bin/sh template='blah blah blah blah $PLACEHOLDER_1 blah ${PLACEHOLDER_2:-"some text"} blah ${PLACEHOLDER_3:-"some lines of text"} and the total is: $((${VAL_1:-0} + ${VAL_2:-0}))' # default operands to zero (or 1) to prevent errors due to unset variables outputfile=output.txt # gears spin, bells ding, values for placeholders are computed PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline string 2' VAL_1=2 VAL_2=4 unset PLACEHOLDER_3 # so we can trigger one of the defaults # Generate file output.txt from variable $template # using placeholders above. echo "$(eval "echo \"$template\"")" > $outputfile
没有sed,没有循环,只是毛茸茸的嵌套和引号.我很确定所有引用都会保护你免受模板文件中的恶意攻击,但我不会保证它.
你仍然可以使用sed在一次传递中进行替换.您只需在一个命令中指定所有替换.
例如.
sed -i 's/PLACEHOLDER_1/string 1/g;s/PLACEHOLDER_2/string 2/g'
在前面的答案的基础上,也许使用数组并计算sed字符串?
#!/bin/sh PLACEHOLDER[0]='string 1' PLACEHOLDER[1]='multiline string 2' s="sed -i " for(( i=0 ; i<${#PLACEHOLDER[*]} ; i++ )) ; do echo ${PLACEHOLDER[$i]} s=$s"s/PLACEHOLDER_$i/${PLACEHOLDER[$i]}/g;" done echo $s
但是,似乎在多行字符串上失败了.
我不知道Bash阵列可能是多么便携.以上片段用"GNU bash,版本3.2.17(1)-release(i386-apple-darwin9.0)"测试