2010-11-29 39 views
1

J'écris un script shell, où je dois extraire le contenu d'un fichier qui est de type:Scripting shell Unix: assigner une valeur du fichier à la variable while while, et utiliser cette valeur en dehors de la boucle

type1 | valueA
type2 | valeurB
type1 | valeurC
type2 | Valued
type3 | valueE
....
typen | valueZ.

Pour chaque type column_1, j'ai une variable cible, qui concatène les valeurs du même type, pour obtenir un résultat comme celui-ci:

var1 = valeurA, valeurC
var2 = valeurB , Valued
var3 = valueE
.....

Script implémente quelque chose comme ceci:

var1="HELLO" 
var2="WORLD" 
... 
cat $file | while read record; do 
    #estract column_1 and column_2 from $record  
if [ $column_1 = "tipo1" ]; then 
    var1="$var1, column_2" ## column_2 = valueB 
elif .... 
.... 
fi 
done 

Mais lorsque je tente d'utiliser la valeur de l'une des variables où j'enchaînée column_2:

echo "$var1 - $var2" 

je reçois les valeurs d'origine:

HELLO - WORLD.  

La recherche sur Internet, je lire que le problème est lié au fait que le pipeline crée un sous-shell dans lequel les valeurs réelles sont copiées.

Existe-t-il un moyen de résoudre ce problème?

Surtout, il y a un moyen qui conviendrait à tous les types de shells, en fait, ce script doit potentiellement tourner sur des shells différents! Je ne souhaite pas utiliser le support de fichiers pour écrire les résultats partiels.

Répondre

0

Oneliner:

for a in `awk "-F|" '{print $1;}' test | sort -u` ; do echo -n "$a =" ; grep -e "^$a" test | awk "-F|" '{ printf(" %s,", $2);}' ; echo "" ; done 
3

Vous n'avez pas besoin d'utiliser cat. Taper quelque chose dans while crée un sous-shell. Lorsque le sous-shell se termine, les valeurs des variables définies dans la boucle sont perdues (comme le serait le changement de répertoire en utilisant cd comme autre exemple.Au lieu de cela, vous devez rediriger votre fichier dans le done:

while condition 
do 
    # do some stuff 
done < inputfile 

Par ailleurs, au lieu de:

while read record 

vous pouvez faire:

while IFS='|' read -r column1 column2 
0

En utilisant awk

awk '{a[$1]=a[$1]==""?$2:a[$1] OFS $2} 
END{for (i in a) print i"="a[i]}' FS=\| OFS=, file 

type1=valueA,valueC 
type2=valueB,valueD 
type3=valueE