J'ai la variable de fichier et les valeurs suivantes
# more file.txt
export worker01="sdg sdh sdi sdj sdk"
export worker02="sdg sdh sdi sdj sdm"
export worker03="sdg sdh sdi sdj sdf"
J'exécute la source afin de lire la variable
# source file.txt
exemple:
echo $worker01
sdg sdh sdi sdj sdk
jusqu'à présent, tout est parfait
mais maintenant je veux lire les variables du fichier et imprimer les valeurs par simple boucle bash je vais lire le deuxième champ et essayer d'imprimer la valeur de la variable
# for i in ` sed s'/=/ /g' /tmp/file.txt | awk '{print $2}' `
do
echo $i
declare var="$i"
echo $var
done
mais son impression uniquement la variable et non les valeurs
worker01
worker01
worker02
worker02
worker03
worker03
production attendue:
worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf
Vous avez export worker01="sdg sdh sdi sdj sdk"
, puis vous remplacez =
avec un espace pour obtenir export worker01 "sdg sdh sdi sdj sdk"
. Les champs séparés par des espaces qui sont export
, worker01
, "sdg
, sdh
, etc.
Il vaut probablement mieux se séparer sur =
, et supprimez les guillemets, donc avec juste le 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
contient le nom de la variable, val
la valeur. Bien sûr, cela n'analyse pas réellement l'entrée, il supprime simplement les guillemets doubles s'ils se trouvent là.
Avec awk seul:
awk -F'"' '{print $2}' file.txt
# To print the variable name as well:
awk '{gsub(/[:=]/," "); gsub(/[:"]/,""); if ($1 = "export") {$1=""; print $0}}' file.txt
pour le boucler, vous pouvez:
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
Si vous souhaitez également imprimer le nom de la variable dans votre boucle, vous pouvez le faire:
#! /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
Production:
$ ./script.sh
worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf
Tout d'abord, vous pouvez obtenir les noms des variables avec cette commande GNU grep, en utilisant une expression régulière compatible Perl:
grep -oP 'export \K[^=]+' file.txt
Ensuite, vous pouvez lire la sortie de cela dans un tableau bash avec:
mapfile -t variables < <(grep -oP 'export \K[^=]+' file.txt)
Cela utilise la commande bash intégrée mapfile
et une substitution de processus .
Enfin, parcourez les noms des variables et utilisez expansion de paramètre indirect pour obtenir les valeurs:
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
Vous pouvez utiliser ce sed
sed -E 's/[^ ]* ([^=]*)="([^"]*)"/\1\n\2/' file.txt
Ou cet awk
awk -F '"|=' '{split($1,a," ");print a[2]"\n"$3}' file.txt