Arrays Bash从配置文件解析数组

Arrays Bash从配置文件解析数组,arrays,linux,bash,parsing,configuration-files,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]} 你有没有想过如何做到这一点?(解释将是一种奖励) 我已经读过这些书,但没有一本能完全满足我的要

我需要为文件中的每个“部分”设置一个数组,其中包含:

[array0]
value1=asdf
value2=jkl

[array1]
value1=1234
value2=5678
我希望能够像这样检索这些值:

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

echo ${array1[value1]}
echo ${array1[value2]}
你有没有想过如何做到这一点?(解释将是一种奖励)

我已经读过这些书,但没有一本能完全满足我的要求


您可以使用

declare-a=(值1值2值3)

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

echo${[index]}

编辑:

好的,从配置文件构造数组。我建议您为要创建的每个阵列使用不同的文件

下面是步骤

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

100 200 300 2.脚本文件(从文件中读取值并准备数组)

数组=() #设置阵列 而IFS=$'\n'读取-a配置 做 数组+=(${config}) 完成<文件名 #访问值 echo${array[0]} echo${array[1]} IFS表示分隔符

-a指定要提取到的数组名,以便您可以在while循环中访问它们。

我正要出去,但我认为您可以执行类似的操作(未经测试),可能会有聪明的人,如@anubhava,将其拾取并完成

eval $(gawk -F= '/^\[/{name=gensub(/\[|\]/,"","g");x=0} /=/{print "name[",x++,"]=",$2," "}' config)
基本上,当它看到一行以“
[
”开头时,它会在变量
name
中提取数组名,并用
gensub()
去掉方括号。然后,当它看到一行中有“
=
”时,它会输出数组名和一个递增的索引“
x
”,以便
eval
提取


必须冲刺-查看示例,了解
stat-s

One
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"

允许

使用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
$whilereadline;do
如果[[$line=~^“[”(.+)“]“$]”;则
arrname=${BASH_重新匹配[1]}
declare-A$arrname
elif[[$line=~^([[u[:alpha:][[u[:alnum:]]*)“=”(.*)”;然后
声明${arrname}[${BASH_REMATCH[1]}]=“${BASH_REMATCH[2]}”
fi
完成${array0[$i]}”已完成
值1=>asdf
值2=>jkl
$表示“${!array1[@]}”中的i,执行echo“$i=>${array1[$i]}”已完成
值1=>1234
值2=>5678

你必须使用Bash吗?这类事情对于Ruby、YAML、Python、JSON、Lua或其他一些事情来说都是微不足道的。我认为最好使用Bash来完成我的工作。我需要使用screen命令和其他相关的东西。关于你实际要做的事情的更多细节可能会有帮助。我了解如何声明和使用数组,但我的问题是从文件中解析数组。我喜欢这个答案,但我发现使用array0[value1]而不是array0[0]更方便。它更适合我的需要。(更新的问题)@AJFerguson很高兴读到这篇文章!事实上,我不得不以一种非常不自然的方式调整内容以满足您的原始需求!让我编辑答案以满足您的新(更自然)需求。@AJFerguson更改(简化)以适应您的新需求。
done < "filename"
space and funnŷ sÿmbòl=value that will have an equal sign: look = it's funny
$ 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