来自配置文件的Bash Parse数组

时间:2014-04-19 07:04:54

标签: arrays linux bash parsing configuration-files

我需要为每个"部分提供一个数组"在包含以下内容的文件中

[array0]
value1=asdf
value2=jkl

[array1]
value1=1234
value2=5678

我希望能够像这样检索这些值:

echo ${array0[value1]}
echo ${array0[value2]}

echo ${array1[value1]}
echo ${array1[value2]}

有关如何实现这一目标的任何想法? (解释将是奖金)

我已经阅读过这些东西,但没有一个完全符合我的想法。

Read a config file in BASH without using "source"

BASH Parsing variables from config file

Array like data structure in bash (config file)?

4 个答案:

答案 0 :(得分:6)

使用bash v4,使用关联数组,将配置文件中的属性存储为实际的bash变量:

$ while read line; do 
    if [[ $line =~ ^"["(.+)"]"$ ]]; then 
        arrname=${BASH_REMATCH[1]}
        declare -A $arrname
    elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then 
        declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
    fi
done < config.conf

$ echo ${array0[value1]}
asdf

$ echo ${array1[value2]}
5678

$ for i in "${!array0[@]}"; do echo "$i => ${array0[$i]}"; done
value1 => asdf
value2 => jkl

$ for i in "${!array1[@]}"; do echo "$i => ${array1[$i]}"; done
value1 => 1234
value2 => 5678

答案 1 :(得分:3)

一个eval - 免费,100%纯Bash可能性:

#!/bin/bash

die() {
   printf >&2 "%s\n" "$@"
   exit 1
}

aryname=''
linenb=0
while read line; do
   ((++linenb))
   if [[ $line =~ ^[[:space:]]*$ ]]; then
      continue
   elif [[ $line =~ ^\[([[:alpha:]][[:alnum:]]*)\]$ ]]; then
      aryname=${BASH_REMATCH[1]}
      declare -A $aryname
   elif [[ $line =~ ^([^=]+)=(.*)$ ]]; then
      [[ -n aryname ]] || die "*** Error line $linenb: no array name defined"
      printf -v ${aryname}["${BASH_REMATCH[1]}"] "%s" "${BASH_REMATCH[2]}"
   else
      die "*** Error line $linenb: $line"
   fi
done

读取标准输入。如果要从文件中读取,请将done更改为:

done < "filename"

表格的行

space and funnŷ sÿmbòl=value that will have an equal sign: look = it's funny

是允许的

答案 2 :(得分:0)

您可以使用

在bash脚本中声明数组

declare -a <array_name>=(value1 value2 value 3)

然后你可以像这样使用它们

echo ${<array_name>[index]}

修改

好的,从配置文件构造数组。我建议为你想要创建的每个数组都有一个不同的文件。

以下是步骤

1.config文件 (创建文件并将值放入其中)

100
200
300

2.script文件 (从文件中读取值并准备一个数组)

    array=()

    #setup array
    while IFS=$'\n' read -a config
    do
      array+=(${config})
    done < file_name

    #access values
    echo ${array[0]}
    echo ${array[1]}

IFS表示分隔符
-a指定要提取到的数组名称,以便可以在while循环中访问它们。

答案 3 :(得分:0)

我即将离开,但我认为你可以做这样的事情(未经测试),也许有些聪明的人,比如@anubhava,会把它拿起并完成它......

eval $(gawk -F= '/^\[/{name=gensub(/\[|\]/,"","g");x=0} /=/{print "name[",x++,"]=",$2," "}' config)

基本上,当它看到以&#34; [&#34;开头的行时它在变量name中选取数组名称,并用gensub()去掉方括号。然后,当它看到一行&#34; =&#34;在其中,它输出数组名称和增加的索引&#34; x&#34;让eval接听。

要点击 - 查看stat -s here的示例。