如何通过Sed提取Shell模板文件中单行内的多个变量?
解决单行多变量模板的变量提取问题
你的核心问题在于原脚本使用的sed命令是贪婪匹配,只能捕获每行最后一个${}包裹的变量。要提取单行中所有${}内的变量,可以改用grep的Perl正则模式结合全局匹配来实现。
修改方案
将原脚本中提取变量的sed命令替换为grep命令,确保能捕获每行所有符合格式的变量:
原代码段:
for env in $(sed -n 's/^[^#].*${\(.*\)}.*/\1/p' $template_file); do
替换为:
for env in $(grep -v '^#' "$template_file" | grep -oP '(?<=\${)[^}]+'); do
解释:
grep -v '^#' "$template_file":过滤掉以#开头的注释行grep -oP '(?<=\${)[^}]+':-o:只输出匹配到的部分,而非整行-P:启用Perl正则表达式(?<=\${):正向预查,匹配${之后的位置(不捕获${本身)[^}]+:匹配任意非}的字符,直到遇到},即提取${}内的变量名
修改后的完整脚本
#!/bin/bash DIR_BASE="$(cd "$(dirname "$0")" && pwd)" render_2_file() { template_file=$1 out_file=$2 set +u # 修改变量提取逻辑,支持单行多变量 for env in $(grep -v '^#' "$template_file" | grep -oP '(?<=\${)[^}]+'); do # debug echo "$env : $(eval echo \$${env})" if [ -z "$(eval echo \$${env})" ]; then echo "environment variable '${env}' not set" missing=true fi done if [ "${missing}" ]; then echo 'Please check the above variable' exit 1 fi eval "cat << EOF $(cat ${template_file}) EOF" >"$out_file" set -u } main(){ # debug generate # VARIABLE_1=var1_val # VARIABLE_2=var1_val # VARIABLE_3=var1_val # single var in one line # TMPL_PATH=$DIR_BASE/tmpl_single.tmpl # OUT_FILE=$DIR_BASE/tmpl_single.json # multi var in one line TMPL_PATH=$DIR_BASE/tmpl_multi.tmpl OUT_FILE=$DIR_BASE/tmpl_multi.json echo "check path = $OUT_FILE" if [ ! -f "$OUT_FILE" ]; then echo "not found, generating" render_2_file "$TMPL_PATH" "$OUT_FILE" if [ $? = 0 ]; then echo "generate successfully" fi else echo "out file existed, no need to generate" fi } main "$@"
测试验证
使用你的tmpl_multi.tmpl模板运行脚本,输出将变为:
not found, generating VARIABLE_1 : environment variable 'VARIABLE_1' not set VARIABLE_2 : environment variable 'VARIABLE_2' not set VARIABLE_3 : environment variable 'VARIABLE_3' not set Please check the above variable
可以看到VARIABLE_1已被成功提取并检测。
内容的提问来源于stack exchange,提问作者moluzhui
相关产品推荐
相关产品推荐

