Rechercher : dans
Par :

[Script Shell] Utilisation du FOR

Dernière réponse le 10 mai 2007 à 17:27:21 Trezeg, le 8 mai 2007 à 11:33:05 
 Signaler ce message aux modérateurs

Bonjour à tous,

J'ai créé un shell qui a pour but d'effectuer un traitement autant de fois qu'il y a la chaine bcp dans le fichier passé en paramètre. Une condition est ajoutée afin de savoir si dans la ligne trouvée avec le mot recherché, apparait l'attribut in (on effectue les opérations) ou out (on s'arrête et on "reboucle").
Voilà ce que cela donne :

#!/bin/ksh
#!/bin/sh
#!/bin/bash

batchFile=/Mesbatches/$1
echo $batchFile
echo $1
for bcp in `grep bcp /Mesbatches/$1 | sed -n '$='`
do
  echo $bcp
  currentBcp=`grep bcp /Mesbatches/$1 | awk '{print $3}'`
  # Ce 3eme champ est l'attribut in ou out
  echo $currentBcp
  if [ "$currentBcp" = "out" ]
  then
    continue
  else
    echo "on est dans le if"
    inputFile=`grep bcp /Mesbatches/$1 | awk '{print $4}'`
   # Ce 4eme champ est un nom de fichier texte
    echo "on est dans l'affichage du fichier input"
    echo $inputFile
    inputCount=`sed -n '$=' $inputFile`
    echo "on affiche le nb de lignes du fichier input"
    echo $inputCount
    outputFile=/Mesbatches/$1.tmp
    echo "on affiche le nom du fichier output"
    echo $outputFile
    outputCount=`grep 'rows copied' $outputFile | nawk '{print $1}'`
    echo $outputCount
        if [ "$inputCount" != "$outputCount" ]
        then
          echo "ERROR on batch $1 !!!"
          echo $inputCount rows in file $inputFile
          echo $outputCount rows processed in database
          return 1
        fi

Quand je lance ce shell avec en parametre, un fichier contenant un seul bcp , ca marche. Par contre à partir de 2, ca se gate...
$ check.sh b_utor (ce fichier contient 6 fois  le terme bcp)
/Mesbatches/b_utor
b_utor
6
out out out in in in
on est dans le if
on est dans l'affichage du fichier input
/Mesbatches/ut_order_hist.txt 
/Mesbatches/ut_issue_master_ext.txt 
/Mesbatches/ut_order.txt 
/Mesbatches/ut_order_hist.txt 
/Mesbatches/ut_issue_master_ext.txt
/Mesbatches/ut_order.txt 
on affiche le nb de lignes du fichier input

on affiche le nom du fichier output
/infotest/prg/files/tmp/uat/b_utor.tmp

$
J'aimerais que le traitement se fasse pour chaque occurence alors que là, il essaie de le faire 6 fois d'un seul coup...
Mon for doit être foireux...
Help me please :-//

Merci

Trez
Configuration: Sun OS 5.8

Meilleures réponses pour « [Script Shell] Utilisation du FOR » dans :
Exécuter un script shell VoirExécution d'un script Pour pouvoir exécuter un script ou un programme en ligne de commande il y a plusieurs possibilités : 1. Le chemin absolu 2. Le chemin relatif 3. Modifier la variable PATH Note: Le Sha...
Guide d'utilisation du Shell pour débutant VoirSHELL BASH - GUIDE D'UTILISATION - Niveau Débutant Introduction Appel aux membres CCM II. C'est quoi le shell ? III. Comment accéder à la ligne de commande IV. Les consoles virtuelles Exemple : Accéder à la console 3 depuis l'interface...

1

jipicy, le 8 mai 2007 à 12:31:19

Salut,

Essaye de changer cette ligne :

for bcp in `grep bcp /Mesbatches/$1 | sed -n '$='`
par :
for bcp in $(seq $(grep bcp /Mesbatches/$1 | sed -n '$='))
;-))
Z'@+...che.
JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

4

Trezeg, le 8 mai 2007 à 14:50:05

Salut jipicy,

il n'a pas l'air d'aimer le seq:

$ check.sh b_utor
/Mesbatches/b_utor
b_utor
check.sh[14]: seq:  not found
Amclt,

Répondre à Trezeg

2

jipicy, le 8 mai 2007 à 14:22:02

La solution du dessus marche pour le nombre d'itération des boucles, mais ne doit pas effectuer le traitement voulu.

Modifie ton script comme ceci :

#!/bin/ksh
#!/bin/sh
#!/bin/bash

batchFile=/Mesbatches/$1
echo $batchFile
echo $1
OIF=$IFS # sauvegarde du séparateur de champs
IFS=$'\n' # initialisation du séparateur de champs (saut de ligne)
for bcp in $(grep bcp /Mesbatches/$1)
do
  echo $bcp
  grep "out" <<<"$bcp" >/dev/null
  if [ "$?" = 0 ]
  then
    continue
  fi
    echo "on est dans le if"
    inputFile=`grep bcp /Mesbatches/$1 | awk '{print $4}'`
   # Ce 4eme champ est un nom de fichier texte
    echo "on est dans l'affichage du fichier input"
    echo $inputFile
    inputCount=`sed -n '$=' $inputFile`
    echo "on affiche le nb de lignes du fichier input"
    echo $inputCount
    outputFile=/Mesbatches/$1.tmp
    echo "on affiche le nom du fichier output"
    echo $outputFile
    outputCount=`grep 'rows copied' $outputFile | nawk '{print $1}'`
    echo $outputCount
        if [ "$inputCount" != "$outputCount" ]
        then
          echo "ERROR on batch $1 !!!"
          echo $inputCount rows in file $inputFile
          echo $outputCount rows processed in database
          return 1
        fi
done
IFS=$OIFS # restauration du séparateur de champs par défaut
;-))
Z'@+...che.
JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

3

Trezeg, le 8 mai 2007 à 14:48:26

Salut jipicy,

voici le résultat de l'execution :

$ check.sh b_utor
/Mesbatches/b_utor
b_utor
check.sh[16]: syntax error at line 21 : `<<' unmatched
:-//

Répondre à Trezeg

5

jipicy, le 8 mai 2007 à 15:13:34

A quoi correspond la ligne 21 ?

Note : Peut être faudrait-il mettre la dernière ligne de mon exemple "IFS=$OIFS" à la sortie du 1er "if ... fi" afin de ne pas perturber le déroulement du reste du script.
Z'@+...che.

JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

6

Trezeg, le 8 mai 2007 à 15:21:49

La ligne 21 correspond à ceci :

grep "out" <<"$bcp" >/dev/null
Amclt,

Répondre à Trezeg

7

jipicy, le 8 mai 2007 à 15:23:20

Il manque un chevron ;-))

grep "out" <<<"$bcp" >/dev/null
C'et 3 qu'il en faut !
Z'@+...che.
JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

8

Trezeg, le 8 mai 2007 à 15:27:55

Je l'avais enlevé car j'ai cru à une faute de frappe ;-)
Cela dit, j'avais essayé sans succès :

$ check.sh b_utor
/Mesbatches/b_utor
b_utor
check.sh[16]: syntax error at line 21 : `<' unexpected
$

Répondre à Trezeg

9

jipicy, le 8 mai 2007 à 15:33:03

Bon vu ton système il doit pas aimer les dernières inventions de bash ;-))

Essaie de parser ta variable comme suit alors :

echo "$bcp" | grep "out" >/dev/null
;-))
Z'@+...che.
JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

10

Trezeg, le 8 mai 2007 à 16:16:27

Re-

Visiblement il a du mal avec les chemins contenus dans les lignes sélectionnées:

$ check.sh b_utor
/Mesbatches/b_utor
b_utor
grep: can't open /i
grep: can't open fotest/prg/uat/scripts/dbElmts/batchM
grep: can't open gt/batches/b_utor
$

Répondre à Trezeg

11

jipicy, le 8 mai 2007 à 16:26:07

Exécute ton script en mode débogage (set -xv) ou lance-le avec l'option (sh -xv ton_script), pour voir ce qui est mal interprété.

Vu ton système (Solaris) reviens à l'ancienne interprétation avec des quotes inversées ( `...` ) au lieu de "$(...)", on sait jamais ;-))
Z'@+...che.

JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

12

Trezeg, le 9 mai 2007 à 11:40:44

Salut jipicy,

J'aimerais revoir mon cheminement afin de trouver une solution. En fait je voudrais stocker toutes lignes contenant les mots "bcp" et " in " (avec un espace avant et après pour in) dans un fichier temporaire:

grep bcp /Mesbatches/$1 | grep " in " > bcp.tmp
Ensuite (et c'est là que je rame...) je veux effectuer mon traitement pour chacune des lignes de bcp.tmp (que je n'aurais plus à trier puisque déjà fait) tout en récupérant le 4ème champ pour chacune de ces lignes.
Aurais-tu une idée ?

Merci pour ton aide.

Trez

Répondre à Trezeg

13

jipicy, le 9 mai 2007 à 11:48:22

Re-

Voir : comment lire un fichier ligne par ligne

;-)) Z'@+...che.

JP : Zen, my Nuggets ! ;-)
Le savoir n'est bon que s'il est partagé.

Répondre à jipicy

14

 Trezeg, le 10 mai 2007 à 17:27:21

Merci jipicy,

je suis parvenu à une solution concernant cette histoire de for en procédant de la façon suivante :

$ more check.sh
#!/bin/ksh
#!/bin/sh
#!/bin/bash

grep bcp Mesbatches/$1 | grep " in " > bcp.tmp
while read line
do
        echo "$line\n"
        inputFile=`echo $line | awk '{print $4}'`
        echo $inputFile
        inputCount=`wc -l $inputFile | awk '{print $1}'`
        echo $inputCount
        outputFile=/infotest/prg/files/tmp/uat/$1.tmp
        echo $outputFile
        outputCount=`grep 'rows copied' $outputFile | nawk '{print $1}'`
        echo $outputCount
        if [ "$inputCount" != "$outputCount" ];then
        echo "ERROR on batch $1 !!!"
        echo $inputCount rows in file $inputFile
        echo $outputCount rows processed in database
        exit 1
fi
done < bcp.tmp
A+

Trez

Répondre à Trezeg
Collection CommentÇaMarche.net