Forum Programmation.shell Script awk : Afficher le nom du fichier en cours de traitement ?

Posté par  . Licence CC By‑SA.
Étiquettes :
1
16
juil.
2019

Bonjour,

Je suis bloqué sur un script et je ne sais pas comment m'en sortir. Je sollicite donc votre aide.

J'ai un script qui me permet d'afficher avec une mise en page des informations provenant de plusieurs CSV.

Voici le script :

    cat /var/www/cgi-bin/LPAR_MAP/*.csv | grep foo | awk -F',|;' '{print $2","$5","$6","$7}' | awk '{
    print "LPARS :" $2
    print "RAM : " $5
    print "CPU 1 : " $6
    print "CPU 2 : " $7
    }'

Ce script va afficher toutes les lignes des fichiers CSV, en ne gardant que les lignes contenant le mot " foo " et n'affichant que les colonnes 2,5,6 et 7.

Voici le type de CSV que je dois traiter :

MO2PPC20;miaibv95;Running;AIX 6.1 6100-09-10-1731;60;0.6;4;DefaultPool;shared;uncap;64
MO2PPC20;miaibv161;Running;AIX 6.1 6100-09-10-1731;60;1.2;4;DefaultPool;shared;uncap;128
MO2PPC20;miaibv246;Running;AIX 6.1 6100-09-10-1731;12;0.5;1;DefaultPool;shared;uncap;64
MO2PPC20;mplaix0088;Running;AIX 7.1 7100-05-02-1810;130;1.5;11;DefaultPool;shared;uncap;64
MO2PPC20;mplaix0306;Running;AIX 7.1 7100-05-02-1810;180;0.5;3;DefaultPool;shared;uncap;64
MO2PPC20;mplaix0087;Running;AIX 7.1 7100-05-02-1810;100;0.4;4;DefaultPool;shared;uncap;64
MO2PPC20;miaibv182;Running;AIX 6.1 6100-09-10-1731;5;0.5;1;DefaultPool;shared;uncap;64
MO2PPC20;mo2vio20b;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
MO2PPC20;mo2vio20a;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
MO2PPC21;mo2vio21b;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
MO2PPC21;mo2vio21a;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
MO2PPC21;oncwasp4;Running;AIX 6.1 6100-09-10-1731;15;0.6;2;DefaultPool;shared;uncap;128
MO2PPC21;mplaix0122;Running;AIX 7.1 7100-05-02-1810;175;2.3;5;DefaultPool;shared;uncap;64

Voici ce que ça donne en sorti :

FRAME :   
------------------

LPARS :mplaix0021
RAM : 11
CPU 1 : 1.0
CPU 2 : 2

LPARS :mplaix0005
RAM : 7
CPU 1 : 0.5
CPU 2 : 2

LPARS :mplaix0025
RAM : 400
CPU 1 : 36.0
CPU 2 : 46

LPARS :mplaix0019
RAM : 120
CPU 1 : 4.0
CPU 2 : 8

LPARS :mplaix0003
RAM : 26
CPU 1 : 0.5
CPU 2 : 2

LPARS :mplaix0007_OLD_DNTSTART
RAM : 0.25
CPU 1 : 0.7
CPU 2 : 7

LPARS :mplaix0009
RAM : 180
CPU 1 : 6.0
CPU 2 : 12

Le problème c'est que même si j'arrive à sélectionner seulement les lignes qui m’intéressent en faisant un grep sur certain mot( ici MO1PPC01 ), je ne sais pas à quel fichier appartiennent les informations affichées. L'idée serait d'avoir quelques choses dans ce style :

FRAME :   
------------------


File : XXXXX.csv

LPARS :mplaix0021
RAM : 11
CPU 1 : 1.0
CPU 2 : 2

LPARS :mplaix0005
RAM : 7
CPU 1 : 0.5
CPU 2 : 2


File : XXXX.csv

LPARS :mplaix0025
RAM : 400
CPU 1 : 36.0
CPU 2 : 46

LPARS :mplaix0019
RAM : 120
CPU 1 : 4.0
CPU 2 : 8

LPARS :mplaix0003
RAM : 26
CPU 1 : 0.5
CPU 2 : 2


File : XXXXXX.csv

LPARS :mplaix0007_OLD_DNTSTART
RAM : 0.25
CPU 1 : 0.7
CPU 2 : 7

LPARS :mplaix0009
RAM : 180
CPU 1 : 6.0
CPU 2 : 12

Bref, que je puisse afficher le nom du fichier avec, en dessous, les informations qui lui sont propres.

Auriez-vous une solution ? Merci d'avance ! :)

  • # difficile ....

    Posté par  . Évalué à 3.

    Deja awk ne connait pas le nom du fichier source vu que tu fais un bel uuoc suivi d'un grep.

    Tu pourrais remolacer ton cat | grep | awk | awk par un simple awk.

    • [^] # Re: difficile ....

      Posté par  . Évalué à 4.

      Awk dispose de la variable FILENAME qui contient le nom du fichier en cours de traitement … En plus au lieu de faire grep | awk ' { … }' tu peux faire awk '/regexp/ { …}'.

      • [^] # Re: difficile ....

        Posté par  . Évalué à 2. Dernière modification le 16 juillet 2019 à 19:19.

        je mettrais un petit : for en bash avec du awk et son option filname dedans.

        je ne suis pas assez bon pour te sortir la ligne de commande directement mais un truc genre :

        for fn in ls /var/www/cgi-bin/LPAR_MAP/*; do
        awk '{ print FILENAME }' tesparametre ;
        done

        ca devrait le faire en reflechissant un peu et t'evite de te faire pourrir avec cat :)

        • [^] # Re: difficile ....

          Posté par  . Évalué à 4. Dernière modification le 16 juillet 2019 à 19:45.

          C'est presque ça.

          Il y a d'ailleurs plusieurs façons de faire.

          Je vais partir de la commande de base (je suppose qu'il y a eu une erreur de copier/coller)

          Soit mon fichier d'entrée toto.txt qui contient :

          MO2PPC20;miaibv95;Running;AIX 6.1 6100-09-10-1731;60;0.6;4;DefaultPool;shared;uncap;64
          MO2PPC20;miaibv161;Running;AIX 6.1 6100-09-10-1731;60;1.2;4;DefaultPool;shared;uncap;128
          MO2PPC20;miaibv246;Running;AIX 6.1 6100-09-10-1731;12;0.5;1;DefaultPool;shared;uncap;64
          MO2PPC20;mplaix0088;Running;AIX 7.1 7100-05-02-1810;130;1.5;11;DefaultPool;shared;uncap;64
          MO2PPC20;mplaix0306;Running;AIX 7.1 7100-05-02-1810;180;0.5;3;DefaultPool;shared;uncap;64
          MO2PPC20;mplaix0087;Running;AIX 7.1 7100-05-02-1810;100;0.4;4;DefaultPool;shared;uncap;64
          MO2PPC20;miaibv182;Running;AIX 6.1 6100-09-10-1731;5;0.5;1;DefaultPool;shared;uncap;64
          MO2PPC20;mo2vio20b;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
          MO2PPC20;mo2vio20a;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
          MO2PPC21;mo2vio21b;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
          MO2PPC21;mo2vio21a;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
          MO2PPC21;oncwasp4;Running;AIX 6.1 6100-09-10-1731;15;0.6;2;DefaultPool;shared;uncap;128
          MO2PPC21;mplaix0122;Running;AIX 7.1 7100-05-02-1810;175;2.3;5;DefaultPool;shared;uncap;64
          

          Si je pars de la premiere commande (corrigée, je suppose qu'il y a erreur de copier/coller a l'origine), j'ai ça :

          cat /tmp/toto.txt | grep MO2PPC | awk -F',|;' '{
          
          print "LPARS :" $2
          
          print "RAM : " $5
          
          print "CPU 1 : " $6
          
          print "CPU 2 : " $7
          
          }'
          LPARS :miaibv95
          RAM : 60
          CPU 1 : 0.6
          CPU 2 : 4
          LPARS :miaibv161
          RAM : 60
          CPU 1 : 1.2
          CPU 2 : 4
          LPARS :miaibv246
          RAM : 12
          CPU 1 : 0.5
          CPU 2 : 1
          LPARS :mplaix0088
          RAM : 130
          CPU 1 : 1.5
          CPU 2 : 11
          LPARS :mplaix0306
          RAM : 180
          CPU 1 : 0.5
          CPU 2 : 3
          LPARS :mplaix0087
          RAM : 100
          CPU 1 : 0.4
          CPU 2 : 4
          LPARS :miaibv182
          RAM : 5
          CPU 1 : 0.5
          CPU 2 : 1
          LPARS :mo2vio20b
          RAM : 7
          CPU 1 : 1.0
          CPU 2 : 2
          LPARS :mo2vio20a
          RAM : 7
          CPU 1 : 1.0
          CPU 2 : 2
          LPARS :mo2vio21b
          RAM : 6
          CPU 1 : 1.5
          CPU 2 : 3
          LPARS :mo2vio21a
          RAM : 6
          CPU 1 : 1.5
          CPU 2 : 3
          
           ... 
          

          Je veux ajouter le filename :

          cat /tmp/toto.txt | grep MO2PPC | awk -F',|;' '{
          print "FILENAME: " FILENAME
          print "LPARS :" $2
          
          print "RAM : " $5
          
          print "CPU 1 : " $6
          
          print "CPU 2 : " $7
          
          }'
          FILENAME: -
          LPARS :miaibv95
          RAM : 60
          CPU 1 : 0.6
          CPU 2 : 4
          FILENAME: -
          LPARS :miaibv161
          RAM : 60
          CPU 1 : 1.2
          CPU 2 : 4
          FILENAME: -
          LPARS :miaibv246
          RAM : 12
          CPU 1 : 0.5
          CPU 2 : 1
          FILENAME: -
          LPARS :mplaix0088
          RAM : 130
          CPU 1 : 1.5
          CPU 2 : 11
          
           ... 
          

          On voit deux problèmes: Le premier, c'est qu'à chaque ligne, le nom de fichier apparait. Le second, c'est qu'on a un '-' (correspond à stdin) parce que l'on a fait un cat | grep | awk.

          Pour corriger le premier problème, il suffit de n'afficher la ligne FILENAME que lorsqu'on traite la première ligne du fichier:

          cat /tmp/toto.txt | grep MO2PPC | awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
          {
          print "LPARS :" $2
          
          print "RAM : " $5
          
          print "CPU 1 : " $6
          
          print "CPU 2 : " $7
          
          }'
          LPARS :miaibv95
          RAM : 60
          CPU 1 : 0.6
          CPU 2 : 4
          LPARS :miaibv161
          RAM : 60
          CPU 1 : 1.2
          CPU 2 : 4
          LPARS :miaibv246
          RAM : 12
          CPU 1 : 0.5
          CPU 2 : 1
          LPARS :mplaix0088
          RAM : 130
          CPU 1 : 1.5
          CPU 2 : 11
          LPARS :mplaix0306
          RAM : 180
          CPU 1 : 0.5
          CPU 2 : 3
          LPARS :mplaix0087
          RAM : 100
          CPU 1 : 0.4
          CPU 2 : 4
          LPARS :miaibv182
          RAM : 5
          CPU 1 : 0.5
          CPU 2 : 1
          LPARS :mo2vio20b
          RAM : 7
          CPU 1 : 1.0
          CPU 2 : 2
          LPARS :mo2vio20a
          RAM : 7
          CPU 1 : 1.0
          CPU 2 : 2
          LPARS :mo2vio21b
          RAM : 6
          CPU 1 : 1.5
          CPU 2 : 3
          LPARS :mo2vio21a
          

          Pour explication, NR correspond a l'enregistrement courant (par défaut la ligne en cours de traitement). On n'affiche le nom du fichier que si la ligne en cours de traitement est la première ligne.

          Ensuite, on veut afficher le nom du fichier. Pour ça il faut virer le cat | grep | awk, tout en gardant la regexp:

          awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
          /MO2PPC/ {
          print "LPARS :" $2
          
          print "RAM : " $5
          
          print "CPU 1 : " $6
          
          print "CPU 2 : " $7
          
          }' /tmp/toto.txt
          FILENAME: /tmp/toto.txt
          LPARS :miaibv95
          RAM : 60
          CPU 1 : 0.6
          CPU 2 : 4
          LPARS :miaibv161
          RAM : 60
          CPU 1 : 1.2
          CPU 2 : 4
          LPARS :miaibv246
          RAM : 12
          CPU 1 : 0.5
          CPU 2 : 1
          LPARS :mplaix0088
          RAM : 130
          CPU 1 : 1.5
          CPU 2 : 11
          LPARS :mplaix0306
          RAM : 180
          CPU 1 : 0.5
          CPU 2 : 3
          LPARS :mplaix0087
          RAM : 100
          CPU 1 : 0.4
          CPU 2 : 4
          

          Pour le traitement, j'ai ajouté un test sur une regexp et du coup on a plus besoin du grep. Il suffit maintenant d'intégrer ça dans une boucle telle que tu l'as indiqué et c'est gagné.

          • [^] # Re: difficile ....

            Posté par  . Évalué à 4. Dernière modification le 16 juillet 2019 à 19:56.

            Ah la boucle for serait plutot du genre :

            for fn in /var/www/cgi-bin/LPAR_MAP/*; do
            awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
            /MO2PPC/ {
            print "LPARS :" $2
            
            print "RAM : " $5
            
            print "CPU 1 : " $6
            
            print "CPU 2 : " $7
            
            }' $fn
            done
            • [^] # Re: difficile ....

              Posté par  . Évalué à 4. Dernière modification le 16 juillet 2019 à 20:25.

              La deuxième méthode …

              Pour info awk traite les fichiers ligne à ligne. Nous avons vu qu'on peut conditionner les traitements effectués sur des lignes en faisant des trucs du genre :

               awk '<test1> { action1} <test2> {action2} ... ' fichier_in
              

              On peut aussi effectuer certaines actions avant que la première ligne du fichier soit parsée et après que la dernière ligne du fichier ait éé parsée:

               awk 'BEGIN { action_avant_parse}  {action2} END {action_apres_parse} ' fichier_in
              

              Exemple, nous allons afficher un texte avant de parser le fichier, afficher chaque ligne du fichier et afficher un texte après parsing :

              $ awk 'BEGIN {print "avant parsing"} {print } END { print "Apres parsing" }' /tmp/toto.txt
              avant parsing
              MO2PPC20;miaibv95;Running;AIX 6.1 6100-09-10-1731;60;0.6;4;DefaultPool;shared;uncap;64
              MO2PPC20;miaibv161;Running;AIX 6.1 6100-09-10-1731;60;1.2;4;DefaultPool;shared;uncap;128
              MO2PPC20;miaibv246;Running;AIX 6.1 6100-09-10-1731;12;0.5;1;DefaultPool;shared;uncap;64
              MO2PPC20;mplaix0088;Running;AIX 7.1 7100-05-02-1810;130;1.5;11;DefaultPool;shared;uncap;64
              MO2PPC20;mplaix0306;Running;AIX 7.1 7100-05-02-1810;180;0.5;3;DefaultPool;shared;uncap;64
              MO2PPC20;mplaix0087;Running;AIX 7.1 7100-05-02-1810;100;0.4;4;DefaultPool;shared;uncap;64
              MO2PPC20;miaibv182;Running;AIX 6.1 6100-09-10-1731;5;0.5;1;DefaultPool;shared;uncap;64
              MO2PPC20;mo2vio20b;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
              MO2PPC20;mo2vio20a;Running;VIOS 2.2.5.20;7;1.0;2;DefaultPool;shared;uncap;192
              MO2PPC21;mo2vio21b;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
              MO2PPC21;mo2vio21a;Running;VIOS 2.2.6.10;6;1.5;3;DefaultPool;shared;uncap;192
              MO2PPC21;oncwasp4;Running;AIX 6.1 6100-09-10-1731;15;0.6;2;DefaultPool;shared;uncap;128
              MO2PPC21;mplaix0122;Running;AIX 7.1 7100-05-02-1810;175;2.3;5;DefaultPool;shared;uncap;64
              Apres parsing
              

              Dans la section BEGIN, certaines variables ne sont pas settées, FILENAME en fait partie (ici je n'affiche que dans la section begin, je n'affiche pas le contenu du fichier ni la fin) :

              $ awk 'BEGIN {print "Filename: " FILENAME}' /tmp/toto.txt
              Filename:
              

              Par contre dans la section END:

              $ awk 'END {print "Filename: " FILENAME}' /tmp/toto.txt
              Filename: /tmp/toto.txt
              
              

              De plus, awk permet de setter des variables en cours de parsing. On peut utiliser des tableaux:

              $ awk -F',|;'  '
              BEGIN {i=0} 
              /MO2PPC/ {LPARS[i]=$2;RAM[i]=$5;CPU1[i]=$6;CPU2[i]=$7;i++} 
              END { 
                print "FILENAME/ " FILENAME; 
                for (j=0;j<i;j++) {
                  print "LPARS: " LPARS[j]; 
                  print "RAM: " RAM[j]; 
                  print "CPU 1: " CPU1[j]; 
                  print "CPU2: " CPU2[j]
                } 
              }' /tmp/toto.txt
              
              FILENAME/ /tmp/toto.txt
              LPARS: miaibv95
              RAM: 60
              CPU 1: 0.6
              CPU2: 4
              LPARS: miaibv161
              RAM: 60
              CPU 1: 1.2
              CPU2: 4
              LPARS: miaibv246
              RAM: 12
              CPU 1: 0.5
              CPU2: 1
              LPARS: mplaix0088
              RAM: 130
              CPU 1: 1.5
              CPU2: 11
              LPARS: mplaix0306
              RAM: 180
              CPU 1: 0.5
              CPU2: 3
              LPARS: mplaix0087
              RAM: 100
              CPU 1: 0.4
              CPU2: 4
              LPARS: miaibv182
              RAM: 5
              CPU 1: 0.5
              CPU2: 1
              LPARS: mo2vio20b
              RAM: 7
              CPU 1: 1.0
              CPU2: 2
              LPARS: mo2vio20a
              RAM: 7
              CPU 1: 1.0
              CPU2: 2
              LPARS: mo2vio21b
              RAM: 6
              CPU 1: 1.5
              CPU2: 3
              LPARS: mo2vio21a
              RAM: 6
              CPU 1: 1.5
              CPU2: 3
              LPARS: oncwasp4
              RAM: 15
              CPU 1: 0.6
              CPU2: 2
              LPARS: mplaix0122
              RAM: 175
              CPU 1: 2.3
              CPU2: 5

              LA section begin initialise l'index utilisé lors du parsing de chaque ligne du fichier. Cet index sera incrémenté à chaque fois qu'une ligne correspondra à la regexp. Puis à la fin, j'utilise une boucle for, qui aura comme compteur la variable j. Cette boucle va parcourir chaque tableau et afficher chaque valeur, jusqu'à ce que l'index j aura atteint la valeur de l'index i. Autrement dit c une façon de parcourir tout le tableau (mais il y en a d'autres).

              • [^] # Re: difficile ....

                Posté par  . Évalué à 3.

                Voici une autre façon de faire.

                Awk peut utiliser des chaines de caractères comme indice de tableau. Au lieu d'initialiser un compteur, on peut indexer nos tableaux avec le nom de lpar.

                $ awk -F',|;'  '                                                                                                                                                                              BEGIN {i=0}                                                                                                                                                                                   /MO2PPC/ {$2;RAM[$2]=$5;CPU1[$2]=$6;CPU2[$2]=$7}                                                                                                                                              ' /tmp/toto.txt        
                

                La boucle for permet, lorsqu'on l'utilise sur un tableau, de setter la variable de boucle avec l'indice du tableau (on aurait pu le faire d'ailleurs sur le tableau a indice numérique de l'exemple précédent). On va utiliser cette propriété en bouclant sur un des tableaux qu'on a initialisé, et utiliser la variable de boucle pour afficher les éléments des autres tableaux :

                $ awk -F',|;'  '                                                                                                                                                                              /MO2PPC/ {$2;RAM[$2]=$5;CPU1[$2]=$6;CPU2[$2]=$7}                                                                                                                                              END {                                                                                                                                                                                           print "FILENAME/ " FILENAME;                                                                                                                                                                  for (j in RAM) {                                                                                                                                                                                print "LPARS: " j;                                                                                                                                                                            print "RAM: " RAM[j];                                                                                                                                                                         print "CPU 1: " CPU1[j];                                                                                                                                                                      print "CPU2: " CPU2[j]                                                                                                                                                                      }                                                                                                                                                                                           }' /tmp/toto.txt                                                                                                                                                                              FILENAME/ /tmp/toto.txt
                LPARS: miaibv246
                RAM: 12
                CPU 1: 0.5
                CPU2: 1
                LPARS: miaibv182
                RAM: 5
                CPU 1: 0.5
                CPU2: 1
                LPARS: mplaix0122
                RAM: 175
                CPU 1: 2.3
                CPU2: 5
                LPARS: mo2vio20a
                RAM: 7
                CPU 1: 1.0
                CPU2: 2
                LPARS: mo2vio20b
                RAM: 7
                CPU 1: 1.0
                CPU2: 2
                LPARS: miaibv95
                RAM: 60
                CPU 1: 0.6
                CPU2: 4
                LPARS: mplaix0306
                RAM: 180
                CPU 1: 0.5
                CPU2: 3
                LPARS: oncwasp4
                RAM: 15
                CPU 1: 0.6
                CPU2: 2
                LPARS: mplaix0087
                RAM: 100
                CPU 1: 0.4
                CPU2: 4
                LPARS: miaibv161
                RAM: 60
                CPU 1: 1.2
                CPU2: 4
                LPARS: mplaix0088
                RAM: 130
                CPU 1: 1.5
                CPU2: 11
                LPARS: mo2vio21a
                RAM: 6
                CPU 1: 1.5
                CPU2: 3
                LPARS: mo2vio21b
                RAM: 6
                CPU 1: 1.5
                CPU2: 3
                
                • [^] # Re: difficile ....

                  Posté par  . Évalué à 2. Dernière modification le 16 juillet 2019 à 21:02.

                  Attention par contre à cette méthode : lorsqu'on utilise des tableaux avec chaines de caractères comme indices, l'ordre d'arrivée des indices dans le tableau n'est pas respecté (on ne sait pas dans quel ordre les indices sont rangés). Ca se voit d'ailleurs lors de l'affichage : il ne se fait pas dans le même ordre que dans les exemples précédents.

            • [^] # Re: difficile ....

              Posté par  . Évalué à 1.

              Bonjour,

              Merci pour votre réponse ! J'avais bien vu la variable FILENAME dans le man mais je n'arrivais pas à la mettre en place ! Votre solution fonctionne parfaitement ! :)

        • [^] # Re: difficile ....

          Posté par  (site web personnel) . Évalué à 7.

          On peut se poser la question d'itérer avec un for sur la sortie de ls (en vrai : à éviter), surtout quand awk peut gérer plusieurs fichiers d'entrée. Exemple en affichant le nom de chacun à chaque fois qu'on est sur la première ligne du fichier courant (« The input record number in the current input file ») :

          awk 'FNR == 1 {print FILENAME}' /var/www/cgi-bin/LPAR_MAP/*

          Si on veut d'une part autoriser autant de fichiers que possible et ne pas être limité par une quelconque limite de taille maximale pour une commande, et d'autre part éviter le cas d'erreur « l'expansion du motif n'a rien donné, donc on travaille sur un fichier dont le nom est exactement /var/www/cgi-bin/LPAR_MAP/* », favoriser find est une bonne idée :

          find /var/www/cgi-bin/LPAR_MAP -type f | while read file; do awk 'stuff' "$file"; done

          Avec un sort au milieu en option si l'ordre est important. Encore mieux avec -print0 et xargs -0 pour éviter les problèmes avec espaces et caractères spéciaux, mais je vais arrêter ma digression ici.

          Debian Consultant @ DEBAMAX

          • [^] # Re: difficile ....

            Posté par  . Évalué à 2.

            Encore mieux avec -print0 et xargs -0 pour éviter les problèmes avec espaces et caractères spéciaux,

            Et pourquoi pas un -exec plutôt qu'un while read file ?

            • [^] # Re: difficile ....

              Posté par  (site web personnel) . Évalué à 1.

              En vrac : ça ne permet pas d'insérer un sort si c'est nécessaire, gérer la syntaxe particulière ({} et ;, ainsi que la position de la partie -exec au sein des paramètres de find) peut être compliqué, c'est plus difficile de garder une trace du nombre d'erreurs, etc.

              Et bien évidemment, cf. les avertissements concernant la sécurité de -exec et -execdir dans la page de manuel de find.

              Debian Consultant @ DEBAMAX

  • # Merci !

    Posté par  . Évalué à 2.

    Merci à vous tous ! Vous m'avez retiré une épine du pied ! :)

    • [^] # Re: Merci !

      Posté par  . Évalué à 2.

      Merci à toi pour avoir soumis ce problème ici (ça m'a amusé de t'aider). J'espère cependant que tu ne t'es pas conténté de faire un copier/coller de la commande, mais que tu as bien compris ce que j'ai fait ;). S'il y a des zones d'ombre, n'hésite pas à demander.

      • [^] # Re: Merci !

        Posté par  . Évalué à 1. Dernière modification le 18 juillet 2019 à 09:48.

        Hello ! :)

        Merci encore pour tes explications ! J'ai parfaitement compris ce que tu as fait, c'est relativement simple en fait… On se demande pourquoi on n'y pense pas avant ! Là malédiction des débutants, vouloir chercher compliquer quand la solution tiens en une seule ligne ! C'est là qu'on voit ceux qui ont de l'expérience ! :)

        Dernière question, dans ton exemple :

        for fn in /var/www/cgi-bin/LPAR_MAP/*; do
        awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
        /MO2PPC/ {
        print "LPARS :" $2
        
        print "RAM : " $5
        
        print "CPU 1 : " $6
        
        print "CPU 2 : " $7
        
        }' $fn
        done
        

        Tu te bases sur " MO2PPC ", cependant, cette variable change constamment puisqu'elle est au choix de l'utilisateur. Ce choix est contenu dans une variable, je dois donc faire quelques choses comme cela ? :

        for fn in /var/www/cgi-bin/LPAR_MAP/*; do
            awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
            /$ma_variable/ {
        
        ou
        
        for fn in /var/www/cgi-bin/LPAR_MAP/*; do
            awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
            /${ma_variable)/ {
        

        Pour qu'elle soit prise en compte ?

        • [^] # Re: Merci !

          Posté par  . Évalué à 2. Dernière modification le 18 juillet 2019 à 13:50.

          Hello.

          Un truc du genre

          for fn in /var/www/cgi-bin/LPAR_MAP/*; do
              awk -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
              /'$ma_variable'/ {
           ... 
          
          

          En gros tu refermes ta quote pour que ta variable soit interprétée par le shell, et tu la réouvres ensuite pour continuer à entrer tes instructions pour awk.

          Il y a d'autres méthodes mais celle-ci me parait la plus simple.

          • [^] # Re: Merci !

            Posté par  . Évalué à 2.

            Une autre façon de faire :

            for fn in /var/www/cgi-bin/LPAR_MAP/*; do
            awk -v var=$ma_variable -F',|;' 'NR==1 { print "FILENAME: " FILENAME }
            $0 ~ $ma_variable {

            L'option -v de awk permet de setter des variables lors de l'appel de la commande :

            $ awk -v var="value" 'BEGIN {print "var: " var}' /tmp/toto.txt
            var: value
            

            Ensuite l'operateur ~ permet de chercher une expression régulière dans une chaine. $0 représente l'enregistrement courant (dans notre cas, la ligne en cours de traitement).

            Personnellement je préfère cette façon de faire à la première, elle évite de s'emmeler les pinceaux dans la gestion des quotes.

  • # simplifier la logique

    Posté par  . Évalué à 2.

    actuellement tu dis à ton shell :

    prend tous les fichiers CSV et regarde dedans (cat /dossier/.csv) => tu as une seule liste pleine de ligne, tu ne sais donc plus quel fichier est traité
    dans le resultat, cherche les lignes qui contiennent **foo
    *,
    traitement avec awk

    dis lui simplement :
    pour chaque fichier csv present dans /dossier/
    affiche son nom
    execute le awk sur le fichier

    ce qui traduit en shell donnerait

    for FICHIER in /dossier/*.csv;
    do
      echo $FICHIER # pour afficher le nom du fichier qu'on traite
      cat $FICHIER | grep foo | awk '{.....}'
    done

    d'apres les exemples données precedemments on peut evidemment faire mieux, en une seule ligne de awk, mais c'est moins lisible (pour debuter)

    • [^] # Re: simplifier la logique

      Posté par  . Évalué à 3.

      d'apres les exemples données precedemments on peut evidemment faire mieux, en une seule ligne de awk, mais c'est moins lisible (pour debuter)

      Ben non, ça donne surtout de mauvaises habitudes. C'est pas compliqué, lorsqu'on explique, de comprendre que awk est une commande qui traite un fichier ligne par ligne, et qu'on peut mettre des conditions sur les lignes traitées (les blocs BEGIN et END étant eux-même des conditions). Par contre faut juste cesser de prendre les gens qui posent les questions pour des idiots, et avoir à l'esprit qu'ils sont capables de comprendre.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.