Bash 从配置文件解析数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23167047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:15:18  来源:igfitidea点击:

Bash Parse Arrays From Config File

arrayslinuxbashparsingconfiguration-files

提问by AJ Ferguson

I need to have an array for each "section" in the file containing:

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

[array0]
value1=asdf
value2=jkl

[array1]
value1=1234
value2=5678

I want to be able to retrieve these values like this:

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

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

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

Any thoughts on how to accomplish this? (Explanations would be a bonus)

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

I've already read these anwsers but none do exactly what I want to do.

我已经阅读了这些 anwsers,但没有一个完全按照我想要做的。

Read a config file in BASH without using "source"

在不使用“源”的情况下在 BASH 中读取配置文件

BASH Parsing variables from config file

BASH 从配置文件解析变量

Array like data structure in bash (config file)?

bash(配置文件)中的类似数据结构的数组?

采纳答案by glenn Hymanman

with bash v4, using associative arrays, store the properties from the config file as actual bash variables:

使用 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

回答by gniourf_gniourf

One eval-free, 100% pure Bash possibility:

一个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

Reads on standard input. If you want to read from a file, change the doneby:

在标准输入上读取。如果要从文件中读取,请done通过以下方式更改:

done < "filename"

Lines of the form

表格的线条

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

are allowed

被允许

回答by Deva

You can declare array in bash scripts with

您可以在 bash 脚本中声明数组

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

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

Then you can use them like this

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

echo ${<array_name>[index]}

echo ${<array_name>[index]}

Edit:

编辑:

Ok, to construct arrays from config file. I would recommend to have a different file for each array you would like to create.

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

So here are the steps

所以这里是步骤

1.config file(create a file and place your values in it)

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

100
200
300

2.script file(read values from file and prepare an array)

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 denotes the delimiter
-a specifies the array name you want to extract to, so that you can access them inside the while loop.

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

回答by Mark Setchell

I am about to go out, but I think you can do something like this (untested) and maybe someone clever , like @anubhava, will pick it up and finish it off...

我正要出去,但我认为你可以做这样的事情(未经测试),也许像@anubhava 这样聪明的人会拿起它并完成它......

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

Basically, when it sees a line starting with "[" it picks up the array name in the variable nameand strips off the square brackets with gensub(). Then, when it sees a line with "=" in it, it outputs the array name and an increasing index "x" for evalto pick up.

基本上,当它看到一行以“ [”开头的行时,它会在变量中选取数组名称name并用 去掉方括号gensub()。然后,当它看到带有“ =”的一行时,它会输出数组名称和一个递增的索引“ x”以eval供选择。

Gotta dash - look at the examples for stat -shere.

必须冲刺 - 看看stat -s这里的例子。