【问题标题】:Bash Parse Arrays From Config FileBash 从配置文件中解析数组
【发布时间】:2014-06-03 17:25:48
【问题描述】:

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

[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)?

【问题讨论】:

  • 你必须使用 Bash 吗?这种事情对于例如,将是完全微不足道的。 Ruby 和 YAML 或 Python 和 JSON 或 Lua 或其他一堆东西。
  • 我认为最好将 Bash 用于我正在做的事情。我需要使用 screen 命令和其他相关的东西。
  • 有关您实际尝试做的事情的更多详细信息会有所帮助。

标签: arrays linux bash parsing configuration-files


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    一个eval-free,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
    

    允许

    【讨论】:

    • 我喜欢这个答案,但我发现使用 array0[value1] 而不是 array0[0] 更方便。它更适合我的需要。 (更新问题)
    • @AJFerguson 很高兴阅读这篇文章!实际上,我不得不以一种非常不自然的方式进行调整以满足您的原始要求!让我编辑答案以适应您的新(更自然)要求。
    • @AJFerguson 已更改(简化)以适应您的新要求。
    【解决方案3】:

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

    declare -a &lt;array_name&gt;=(value1 value2 value 3)

    然后你可以这样使用它们

    echo ${&lt;array_name&gt;[index]}

    编辑:

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

    下面是步骤

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

    100 200 300

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

    数组=() #设置数组 而 IFS=$'\n' 读取 -a 配置 做 数组+=(${config}) 完成

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

    【讨论】:

    • 我了解如何声明和使用数组,但我的问题是从文件中解析数组。
    【解决方案4】:

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

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

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

    必须冲刺 - 查看stat -s here 的示例。

    【讨论】:

      猜你喜欢
      • 2013-05-10
      • 1970-01-01
      • 2012-02-16
      • 2011-10-12
      • 1970-01-01
      • 2012-09-13
      • 2021-06-16
      • 2021-08-14
      相关资源
      最近更新 更多