我编写一个脚本来自动为我自己的网络服务器创建Apache和PHP的配置文件。我不想使用任何GUI像CPanel或ISPConfig。
我有一些Apache和PHP配置文件的模板。 Bash脚本需要读取模板,使变量替换和输出解析的模板到某个文件夹。什么是最好的方法呢?我可以想几种方法。哪一个是最好的或可能有一些更好的方法来做到这一点?我想在纯Bash(这很容易在PHP中)
1)How to replace ${} placeholders in a text file?
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"
BTW,我如何将输出重定向到外部文件?如果变量包含,例如,引号,我需要转义吗?
2)使用cat& sed用每个变量的值替换:
给定template.txt:
The number is ${i} The word is ${word}
命令:
cat template.txt | sed -e "s/\${i}/1/" | sed -e "s/\${word}/dog/"
似乎对我不好,因为需要逃脱许多不同的符号和许多变量的线将太tooo长。
你能想到一些其他优雅和安全的解决方案吗?
您可以使用:
原文链接:https://www.f2er.com/bash/392221.htmlperl -p -i -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg' < template.txt
用相应的环境变量替换所有$ {…}字符串(不要忘记在运行此脚本之前导出它们)。
对于纯bash这应该工作(假设变量不包含$ {…}字符串):
#!/bin/bash while read -r line ; do while [[ "$line" =~ (\$\{[a-zA-Z_][a-zA-Z_0-9]*\}) ]] ; do LHS=${BASH_REMATCH[1]} RHS="$(eval echo "\"$LHS\"")" line=${line//$LHS/$RHS} done echo "$line" done
。解决方案不挂起,如果RHS引用一些引用自身的变量:
#!/bin/bash line="$(cat; echo -n a)" end_offset=${#line} while [[ "${line:0:$end_offset}" =~ (.*)(\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})(.*) ]] ; do PRE="${BASH_REMATCH[1]}" POST="${BASH_REMATCH[4]}${line:$end_offset:${#line}}" VARNAME="${BASH_REMATCH[3]}" eval 'VARVAL="$'$VARNAME'"' line="$PRE$VARVAL$POST" end_offset=${#PRE} done echo -n "${line:0:-1}"
警告:我不知道一种方法来正确处理bash中的NUL的输入,或保留尾随换行符的数量。最后一个变体是因为它是因为“爱”二进制输入:
> read将解释反斜杠。> read -r不会解释反斜杠,但如果最后一行没有以换行符结束,它仍会丢弃。>“$(…)”将剥离与存在的许多尾随换行符,所以我结束… with; echo -n a并使用echo -n“$ {line:0:-1}”:这将删除最后一个字符(它是一个),并保留与输入(包括否)一样多的尾随换行。