使用 sed/awk 从 ini 样式文件中读取值
Reading value from an ini style file with sed/awk
我写了一个简单的 bash 函数,它会从 ini 文件(由变量 CONF_FILE
定义)读取值并输出它
getConfValue() {
#getConfValue section variable
#return value of a specific variable from given section of a conf file
section=
var=""
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 的解决方案也很好。
坚持使用 sed
,您可以使用 ^
将 var
搜索定位到记录的开头,并以等号结尾:
"/\[$section\]/,/\[/{/^$var=/p}"
如果您担心记录前面的空白,您可以考虑以下原因:
"/\[$section\]/,/\[/{/^(\W|)$var=/p}"
^(\W|)$var=
表示 "if there is whitespace at the beginning (^(\W
) or nothing (|)
) before your variable concatenated with an equal sign ($var=
)."
如果你想切换到 awk,你可以使用类似的东西:
val=$(awk -F"=" -v section=$section -v var=$var '=="["section"]"{secFound=1}secFound==1 && ==var{print ; secFound=0}' $CONF_FILE)
awk
命令将记录按相等 -F"="
拆分。然后,如果记录中的第一个字段是您的部分 (=="["section"]"
),则将变量 secFound
设置为 1。然后...如果 secFound
为 1,并且第一个字段正好等于您的var
变量 (secFound==1 && ==var
) 然后打印出第二个字段 ({print }
) 并将 secFound
设置为 0 所以我们不会选择任何其他 Test
键.
我写了一个简单的 bash 函数,它会从 ini 文件(由变量 CONF_FILE
定义)读取值并输出它
getConfValue() {
#getConfValue section variable
#return value of a specific variable from given section of a conf file
section=
var=""
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 的解决方案也很好。
坚持使用 sed
,您可以使用 ^
将 var
搜索定位到记录的开头,并以等号结尾:
"/\[$section\]/,/\[/{/^$var=/p}"
如果您担心记录前面的空白,您可以考虑以下原因:
"/\[$section\]/,/\[/{/^(\W|)$var=/p}"
^(\W|)$var=
表示 "if there is whitespace at the beginning (^(\W
) or nothing (|)
) before your variable concatenated with an equal sign ($var=
)."
如果你想切换到 awk,你可以使用类似的东西:
val=$(awk -F"=" -v section=$section -v var=$var '=="["section"]"{secFound=1}secFound==1 && ==var{print ; secFound=0}' $CONF_FILE)
awk
命令将记录按相等 -F"="
拆分。然后,如果记录中的第一个字段是您的部分 (=="["section"]"
),则将变量 secFound
设置为 1。然后...如果 secFound
为 1,并且第一个字段正好等于您的var
变量 (secFound==1 && ==var
) 然后打印出第二个字段 ({print }
) 并将 secFound
设置为 0 所以我们不会选择任何其他 Test
键.