shell脚本:如何读取属性文件

时间:2018-03-07 10:15:18

标签: shell awk

目前,我有一个这样的属性文件:

[default]
aa=aa
bb=bb

[dev]
aa=aa
dd=dd

如果我想在某个部分获得某个值,我可以使用以下代码:

awk -F '=' '/\['$section'\]/{a=1}a==1&&$1~/'$key'/{print $2;exit}' $configfile

但是我怎样才能获得整个部分,例如我想要一个列表来保存 dev 部分中的所有值?

任何人都可以帮忙吗?

[编辑]

我可能希望将一个部分中的所有值保存在这样的列表中:

list=()
list=`get_section dev`

,列表内容可以是:

aa bb

再次感谢您的亲切帮助!

4 个答案:

答案 0 :(得分:3)

Awk 解决方案:

section="dev"
awk -F'=' -v s="$section" '/^\[/{ gsub(/[\[\]]/, "", $1); f = ($1 == s); next }
                           NF && f{ print $2 }' file

输出:

aa
dd

答案 1 :(得分:1)

我认为以下是我提取部分的解决方案:

awk '/^\[/{x=0} $1=="["section"]"{x=1} x' section="$section" my.ini

这可以避免部分中出现空白行的任何问题。但是,它不打印结果列表,或者将它们转换为shell变量,我收集的是你正在寻找的内容。

如果你的shell是bash,你可能会利用数组,并完全避免使用awk。关联数组是bash 4的一个特性:

declare -A conf

while IFS='=' read var val; do
    if [[ $var == \[*] ]]; then
        section="${var//[^[:alnum:]]/}"    # strip invalid chars from variable name
    elif [[ -n "$val" ]]; then
        echo " > ${section}_$var=$val"     # debugging
        declare "${section}_$var=$val"     # set to vars, bash 3
        conf["${section}_$var"]="$val"     # store in associative array, bash 4
    fi
done < my.ini

这会将整个配置存储在变量或bash数组中。如果您想从值中修剪前导空格,最简单的方法是设置IFS='= '而不是'='

POSIX shell中的等价物可能类似于:

while IFS='=' read var val; do
    if expr "$var" : '[[].*[]]$' >/dev/null; then
        section="$(echo "$var" | tr -d '][')"
    elif [ -n "$val" ]; then
        echo " > ${section}_$var=$val"          # debugging
        eval "${section}_$var=\"$val\""         # set to vars, POSIX
    fi
done < my.ini

这样的结果将是一组类似于上面提到的declare bash 3选项的变量。但是对于POSIX,我们会遇到eval

如果你想要一个随机访问方法从bash中的一个部分中提取变量,你可以将它作为一个函数来实现:

function confitem() {

    # Usage: confitem section itemname

    local -A conf
    local var val section
    local retval=1

    while IFS='=' read var val; do
        if [[ $var == \[*] ]]; then
            section="$var"
        elif [[ -n $val ]] && [[ $section == $1 ]] && [[ $var == $2 ]]; then
            printf '%s' "$val"     # print the result
            retval=0               # set a return value for the function
            break                  # and quit the loop.
        fi
    done < my.ini
    return $retval

}

答案 2 :(得分:0)

如果输入与任何部分中没有空行一致,并且部分之间的空行不包含任何空格,则可以清除记录分隔符,如下所示:

awk '$1 == "["section"]"' section="$section" RS= "$configfile"

awk '$2 == s' s="$section" FS=[][] RS= "$configfile"

我不确定你的意思是&#34;一个包含所有值的列表&#34;,但是如果你只想打印这些值,你可以使用cut -d= -f2轻松进行后期处理

答案 3 :(得分:0)

使用sed

section=dev
sed '/'"$section"'/,/^$/!d;/=/!d;s/.*=\(.*\)/\1/' "$configfile"