【问题标题】:Reading value from an ini style file with sed/awk使用 sed/awk 从 ini 样式文件中读取值
【发布时间】:2016-10-18 11:59:12
【问题描述】:

我写了一个简单的 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"
}

问题是它不会忽略 cmets,如果一个部分名称中的多个变量共享公共子字符串,它就会遇到麻烦。

示例 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 的解决方案也可以。

【问题讨论】:

    标签: bash awk sed ini


    【解决方案1】:

    坚持使用sed,您可以使用^var 搜索锚定到记录的开头并以等号结束:

    "/\[$section\]/,/\[/{/^$var=/p}"
    

    如果您担心记录前的空白,您可以考虑:

    "/\[$section\]/,/\[/{/^(\W|)$var=/p}"
    

    ^(\W|)$var= 表示“如果变量与等号 ($var=) 连接之前的开头有空格 (^(\W) 或没有空格 (|))。”

    如果你想切换到 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 变量 (@ 987654337@) 然后打印出第二个字段 ({print $2}) 并将 secFound 设置为 0,这样我们就不会选择任何其他 Test 键。

    【讨论】:

    • 谢谢!效果很好。这种方法的唯一问题是,如果变量名前面有空格(或制表符),它将失败。是否可以在搜索字符串中添加“”*之类的内容?
    • 我更新了一个 sed 示例,该示例说明了键/值对之前的空格。
    猜你喜欢
    • 2013-02-06
    • 2014-04-28
    • 2011-04-13
    • 2013-08-02
    • 2014-02-20
    • 2022-01-21
    • 2021-02-28
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多