pb script ksh - Shell/Batch - Programmation
Marsh Posté le 01-09-2006 à 17:58:49
suya95 a écrit : Bonjour, j'espere que vous pourrez m'aider.
|
Déjà, dans ce type de travail, tu peux remplacer
cat INVENTAIRE.csv | grep -i mon >$mts |
par
grep -i mon INVENTAIRE.csv >$mts |
car le grep peut aussi bien traiter l'entrée standard qu'un fichier passé en paramètre
Par ailleurs, tu peux éviter le fichier temporaire en mettant directement
grep -i mon INVENTAIRE.csv |while read ligne |
Hé oui, si le read peut lire des infos venant d'un "cat", il peut aussi lire des infos venant d'un "grep". Mais cela ne résoudra pas ton pb...
Petite question rapide: est-ce que "$ligne" contient bien des valeurs séparées par un espace ou une tabulation et que "$5" et "$7" sont bien des nombres ??? Parce que si le séparateur est autre chose (style point-virgule), le "set" ne découpera rien et mettra tout dans $1 donc $5 et $7 seront égaux à 0 dont tes totaux seront aussi à 0 en fin de boucle !!!
Sinon, une remarque générale qui s'applique au Bourne Shell et Bourne Again Shell (elle ne s'applique pas au ksh mais c'est pour la portabilité)
En shell de base (Bourne et associés), le pb de cette structure "cat machin |while read ...", c'est que le pipe te génére un sous-processus dans lequel tes variables sont bien remplies mais perdues à la fin du done. Tu peux en avoir la preuve si tu mets un "echo" dans ta boucle !!!
Et inutile d'essayer avec "export". Je l'ai déjà fait et ça marche pas car le "export" sert à rendre visible une variable depuis un père vers un fils, alors que ton script initial cherche à faire remonter des variables depuis un fils vers son père...
Donc en shell de base, tu as 2 solutions pour résoudre le pb (qui fonctionnent aussi en ksh)
1) tu utilises des parenthèses pour grouper le while et le echo final dans le même processus
cat $mts | ( while read ligne |
2) tu t'arranges pour ne pas avoir de pipe. Par exemple, pour lire un fichier, tu peux le stocker dans un canal numéroté que tu liras ensuite quand tu en auras envie, style
|
La solution 2 est parfaite pour lire un fichier. Malheureusement, elle ne te permettra pas de lire une commande du style
commande_quelconque | while read ligne |
Ou alors il te faudra créer un fichier temporaire contenant le résultat de "commande_quelconque" (ce que tu avais fait avec "grep ... >$mts" ) que tu pourras ensuite stocker dans un canal numéroté pour le lire...
Marsh Posté le 02-09-2006 à 15:09:12
Au lieu de faire :
cat $mts| while read LIGNE |
il vaut mieux :
while read LIGNE |
On utilise un process de moins, et de plus les modifications de variables effectuées dans la bouche while ne sont pas perdues.
Il est possible de lire plusieurs variables avec l'instruction read :
while read mts_1 mts_2 mts_3 mts_4 mts_int mts_6 mts_adm _mts_8 |
Si le séparateur de champ n'est pas l'espace, on peut le spécifier sur la commande read, par exemple pour le séparateur ';' :
IFS=';' read field1 field2 |
Une autre technique pour lire le fichier et faite les cumuls :
awk ' |
Jean-Pierre.
Marsh Posté le 01-09-2006 à 08:53:24
Bonjour, j'espere que vous pourrez m'aider.
Voila ci dessous mon petit script, mais le fait et qu'en resultat je devrais avoir un chiffre qui est 1630 mais à la place il met met 0 et j'ai passé 2h dessus sans savoir pourquoi, si quelqu'un sait mon erreur.
Merci de votre aide
#!/bin/ksh
typeset -i tot_mts_int=0
typeset -i tot_mts_adm=0
typeset -i tot_final=0
mts=mts1.csv
rm $mts
touch $mts
total_port=total1.csv
rm $total_port
touch $total_port
cat INVENTAIRE.csv | grep -i mon >$mts
cat $mts |while read LIGNE
do
set $LIGNE
tot_mts_int=$(($tot_mts_int+$5))
tot_mts_adm=$(($tot_mts_adm+$7))
tot_final=$(($tot_mts_int)-($tot_mts_adm))
done
echo "Nbres Int MTS" >$total_port
echo "${tot_final}" >>$total_port