bash + read variables & values from file by bash script

47,324

Solution 1

You have export worker01="sdg sdh sdi sdj sdk", then you replace = with a space to get export worker01 "sdg sdh sdi sdj sdk". The space separated fields in that are export, worker01, "sdg, sdh, etc.

It's probably better to split on =, and remove the quotes, so with just the shell:

$ while IFS== read -r key val ; do
    val=${val%\"}; val=${val#\"}; key=${key#export };
    echo "$key = $val";
  done < vars
worker01 = sdg sdh sdi sdj sdk
worker02 = sdg sdh sdi sdj sdm
worker03 = sdg sdh sdi sdj sdf

key contains the variable name, val the value. Of course this doesn't actually parse the input, it just removes the double quotes if they happen to be there.

Solution 2

First, you can get the variables names with this GNU grep command, using a Perl-compat regex:

grep -oP 'export \K[^=]+' file.txt

Then, you can read the output of that into a bash array with:

mapfile -t variables < <(grep -oP 'export \K[^=]+' file.txt)

That uses the bash builtin mapfile command and a process substitition.

Last, iterate over the variable names and use indirect parameter expansion to get the values:

for v in "${variables[@]}"; do 
    printf "varname=%s\tvalue=%s\n" "$v" "${!v}"
done
varname=worker01        value=sdg sdh sdi sdj sdk
varname=worker02        value=sdg sdh sdi sdj sdm
varname=worker03        value=sdg sdh sdi sdj sdf

Solution 3

With awk alone:

awk -F'"' '{print $2}' file.txt
# To print the variable name as well:
awk '{gsub(/[:=]/," "); gsub(/[:"]/,""); if ($1 = "export") {$1=""; print $0}}' file.txt

to loop it you can:

for i in "$(awk -F\" '{print $2}' file.txt)"; do
    var="$i"
    echo "$var"
done
my_array=($(awk -F\" '{print $2}' file.txt))
for element in "${my_var[@]}"; do
    another_var="$element"
    echo "$another_var"
done

If you also want to print the variable name in your loop you can do this:

#! /usr/bin/env bash -
while read -r line; do
    if [[ "$(awk '{print $1}' <<<"$line")" == 'export' ]]; then
        var_name="$(awk '{print $2}' <<<"$line" | awk -F'=' '{print $1}')"
        var_value="$(awk -F\" '{print $2}' <<<"$line")"
        echo -e "${var_name}\n${var_value}"
    else
        continue
    fi
done<file.txt

Output:

$ ./script.sh
worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf
Share:
47,324
yael
Author by

yael

Updated on September 18, 2022

Comments

  • yael
    yael almost 2 years

    I have the following file variable and values

    # more file.txt
    export worker01="sdg sdh sdi sdj sdk"
    export worker02="sdg sdh sdi sdj sdm"
    export worker03="sdg sdh sdi sdj sdf"
    

    I perform source in order to read the variable

    # source file.txt
    

    example:

    echo $worker01
    sdg sdh sdi sdj sdk
    

    until now every thing is perfect

    but now I want to read the variables from the file and print the values by simple bash loop I will read the second field and try to print value of the variable

    #  for i in ` sed s'/=/ /g'  /tmp/file.txt | awk '{print $2}' `
       do  
       echo $i
       declare var="$i"
       echo $var
       done
    

    but its print only the variable and not the values

    worker01
    worker01
    worker02
    worker02
    worker03
    worker03
    

    expected output:

    worker01
    sdg sdh sdi sdj sdk
    worker02
    sdg sdh sdi sdj sdm
    worker03
    sdg sdh sdi sdj sdf
    
  • sfscs
    sfscs over 3 years
    Working through this answer and learning all the techniques used here taught me a lot about bash, parameters and modifying shell behavior. I highly recommend iterating and researching until one understands everything mentioned in it. Thank you.