我写了一个简单的bash函数,它将从ini文件中读取值(由变量CONF_FILE
定义)并输出
getConfValue() {
#getConfValue section variable
#return value of a specific variable from given section of a conf file
section=$1
var="$2"
val=$(sed -nr "/\[$section\]/,/\[/{/$var/p}" $CONF_FILE)
val=${val#$var=}
echo "$val"
}
问题在于,如果节名称中的多个变量共享公共子串,它不会忽略注释并遇到麻烦。
示例ini文件:
[general]
# TEST=old
; TEST=comment
TEST=new
TESTING=this will be output too
PATH=/tmp/test
正在运行getConfValue general PATH
会按预期输出/tmp/test
,但正在运行getConfValue general TEST
会显示此方法存在的所有问题。
如何解决这个问题?
我知道有一些像crudini
这样的专用工具或python,perl和php的工具,但是我不希望为简单的配置文件解析添加额外的依赖项。结合awk而不是sed的解决方案也可以。
答案 0 :(得分:6)
坚持使用sed
,您可以使用var
将^
搜索锚定到记录的开头,并以等号结束:
"/\[$section\]/,/\[/{/^$var=/p}"
如果您担心记录前面的空白,可以说明这一点:
"/\[$section\]/,/\[/{/^(\W|)$var=/p}"
^(\W|)$var=
在您的变量与等号(^(\W
)连接之前,表示“如果开头有空格(|)
)或没有任何内容($var=
)。 “
如果您想切换到awk,可以使用以下内容:
val=$(awk -F"=" -v section=$section -v var=$var '$1=="["section"]"{secFound=1}secFound==1 && $1==var{print $2; secFound=0}' $CONF_FILE)
awk
命令将记录拆分为-F"="
。然后,如果记录中的第一个字段是您的部分($1=="["section"]"
),则将变量secFound
设置为1.然后......如果secFound
为1且第一个字段完全等于您的var
变量(secFound==1 && $1==var
)然后打印出第二个字段({print $2}
)并将secFound
设置为0,这样我们就不会选择任何其他Test
个键