Bash Parse Arrays From Config File

前端 未结 4 1853
孤独总比滥情好
孤独总比滥情好 2021-02-06 12:28

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 t

相关标签:
4条回答
  • 2021-02-06 12:58

    One eval-free, 100% pure Bash possibility:

    #!/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 done by:

    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

    0 讨论(0)
  • 2021-02-06 13:09

    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...

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

    Basically, when it sees a line starting with "[" it picks up the array name in the variable name and 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 eval to pick up.

    Gotta dash - look at the examples for stat -s here.

    0 讨论(0)
  • 2021-02-06 13:10

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

    $ 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
    
    0 讨论(0)
  • 2021-02-06 13:12

    You can declare array in bash scripts with

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

    Then you can use them like this

    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)

    100
    200
    300
    

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

        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.

    0 讨论(0)
提交回复
热议问题