bash + ler variáveis e valores do script file by bash

6

Eu tenho a seguinte variável e valores de arquivo

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

Eu faço o código fonte para ler a variável

# source file.txt

exemplo:

echo $worker01
sdg sdh sdi sdj sdk

até agora tudo é perfeito

mas agora eu quero ler as variáveis do arquivo e imprimir os valores por simples loop bash vou ler o segundo campo e tentar imprimir valor da variável

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

mas imprime apenas a variável e não os valores

worker01
worker01
worker02
worker02
worker03
worker03

resultado esperado:

worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf
    
por yael 25.12.2017 / 17:40

4 respostas

5

Você tem export worker01="sdg sdh sdi sdj sdk" e, em seguida, substitui = por um espaço para obter export worker01 "sdg sdh sdi sdj sdk" . Os campos separados por espaço são export , worker01 , "sdg , sdh , etc.

Provavelmente é melhor dividir em = e remover as aspas, apenas com o 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 contém o nome da variável, val o valor. É claro que isso não analisa realmente a entrada, apenas remove as aspas duplas se elas estiverem lá.

    
por 25.12.2017 / 17:48
2

Apenas com awk :

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

para fazer um loop, você pode:

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

Se você também quiser imprimir o nome da variável no seu loop, poderá fazer isso:

#! /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

Saída:

$ ./script.sh
worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf
    
por 25.12.2017 / 17:45
2

Primeiro, você pode obter os nomes das variáveis com este comando GNU grep, usando um regex Perl-compat:

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

Depois, você pode ler a saída disso em uma matriz bash com:

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

Isso usa o comando bash mapfile e um processo de substituição .

Por último, repita os nomes das variáveis e use indireto expansão do parâmetro para obter os valores:

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
    
por 27.12.2017 / 16:43
0

Você pode usar este sed

sed -E 's/[^ ]* ([^=]*)="([^"]*)"/\n/' file.txt

Ou este awk

awk -F '"|=' '{split($1,a," ");print a[2]"\n"$3}' file.txt
    
por 25.12.2017 / 21:31