Partage
  • Partager sur Facebook
  • Partager sur Twitter

Awk et bash

    10 novembre 2019 à 1:02:53

    Bonsoir à tous,

    Bon voilà, en gros j'ai essayé de lire des fichier qui son formaté par des espaces. Jusque la pas difficile j'utilise awk

    vaf -v  ${newsrv}| awk -F" " '{ print $2 $3}'|while read newLine;

    vaf est un autre script qui me donne tous les fichiers donc j'ai besoin. Je le pipe dans un awk ou j'ai besoin de la 2eme et 3eme colonne. Et je le pipe dans une boucle car beaucoup d'entré et je dois comparer les 2 collones.

    Mon problème c'est que je dois partager les information lue par awk et mon script. Je ne connais pas bien la programmation awk.

    J'ai vue que je pouvais utilisé l'option -v . Mais je n'y arrive pas. Est-il possible d'avoir un truc du genre

    $Varbash= $2 # #2 de awk

    Existe il des autre fonction que print? 

    Ou puis apprendre convenablement awk car je comprend pas quand il faut écrire un script awk .

    Merci :)


    • Partager sur Facebook
    • Partager sur Twitter
      10 novembre 2019 à 7:16:45

      salut,

      je le pipe dans une boucle car beaucoup d'entré et je dois comparer les 2 collones.

      ce n'est pas utile : awk peut le faire :

      tonScript | awk '$2 == $3 {print "deuxième et troisième colonnes égales"}'

      je dois partager les information lue par awk et mon script. Je ne connais pas bien la programmation awk.

      ce n'est pas clair, tu peux nous donner quelques exemples représentatifs, s'il te plaît ?

      l'option -v de awk affecte une variable pour awk :

      $ echo '' | awk -v maVar="blabla" '{print maVar}'
      blabla

      ça permet d'assigner des variables de l'environnement courant dans awk :

      maVarShell="c'est le shell"
      echo '' | awk -v maVarAwk="$maVarShell" '{print maVarAwk}'

      sinon, il faudrait faire comme ça :

      echo '' | awk '{print '"$maVarShell"'}'
      • Partager sur Facebook
      • Partager sur Twitter

      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

        10 novembre 2019 à 12:31:58

        Salut et merci de ta réponse :)

        Mon script compare deux fichiers ensemble. J'utilise donc deux fois awk de cette manière

        vaf -v  ${olssrv}| awk -F" " '{ print $2 $3}'|while read oldLine;
        
        vaf -v  ${newsrv}| awk -F" " '{ print $2 $3}'|while read newLine;
        

        Ce qui m'interesse est dans les variable $2 et $3 je dois comparer le $2 et le $2.

        Quand les deux colonnes sont identique je compare le $3 et $3.

        Quand le deuxième test est fait je dois récuperer le nom contenu dans $2 et l'envoyer dans un fichier log.

        Ce que je voudrais c'est récuperer la colonne $2 de awk dans le script pour traiter tout ça.

        Donc 

        $ echo '' | awk -v maVar="blabla" '{print maVar}'
        blabla

        Ne m'interesse pas car je partage une variable shell avec awk, je voudrais faire le contraire partager $2 de awk avec mon script

        J'espere que c'est plus claire et encore merci

        -
        Edité par Don_raftapss 10 novembre 2019 à 12:33:34

        • Partager sur Facebook
        • Partager sur Twitter
          10 novembre 2019 à 12:46:17

          selon moi, il y a un problème d'algorithme. ;)

          que fait précisément le script vaf ?

          j'imagine, sans avoir testé, quelque chose comme ça en bash (pour avoir accès à la Substitution de processus <()) : 

          awk 'NR == FNR{array[$2]++; next}{if ($2 == array[$2]){ cmd; cmd;}}' <(vaf -v "$old") <(vaf -v "$new")

          en gardant à l'esprit que la solution est probablement dans le script vaf qui ne fait pas son boulot...

          • Partager sur Facebook
          • Partager sur Twitter

          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

            10 novembre 2019 à 13:40:44

            Non vaf fais bien sont travailles. Il permet de lister les fichier .c et .h d'un fichier binaire et de donner les versions

            Il donne une réponse du style.

            chemin/copie.h v2 

            chemin/copie.c v3

            Mais le fichier binaire est compose de centaine de fichier .h .c etc.

            Moi ce que je voudrais c'est partager les variable $2,$3 etc... qui représente les colonnes du awk. Avec mon script shell.

            vaf -v  ${olssrv}| awk -F" " '{ print $2 $3}'

            Le $2 et $3 représente mes deux collone

            Je voudrais faire 

            nomFichier=""
            Version=""
            vaf -v  ${olssrv}| awk -F" " '{ "$nomFichier"=$2 "$version"=$3}'

            Je sais que cela ne va pas comme ça j'ai essayer :D




            • Partager sur Facebook
            • Partager sur Twitter
              10 novembre 2019 à 14:03:43

              le problème, c'est que la commande vaf affiche une liste, et que chaque élément/ligne effacera les valeurs les précédentes.

              quelle comparaison dois-tu effectuer ? sur quels éléments ? et quel est le résultat attendu en fonction de la comparaison pour quelques éléments représentatifs ?

              je comprends que tu veuilles à ta façon, mais, en général, c'est une mauvaise idée qui amène à chaque étape plus de complications.

              on peut forcer un cheval à faire ce qu'on veut, mais c'est alors un cheval auquel on ne lâchera jamais la bride, et qui n'aura jamais la souplesse, la beauté d'un cheval que l'on accompagne.

              • Partager sur Facebook
              • Partager sur Twitter

              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                10 novembre 2019 à 14:57:03

                La commande vaf n'affiche pas de liste car elle dispose de l'option -v . Mais elle parcour cette liste quand même d'ou le fait de vouloir lire ligne par ligne

                Je dois comparer l'ancien fichier avec un nouveau. De manière à savoir si la version de se fichier à changer. 

                	vaf -v  ${oldsrv}| awk -F" " '{ print $2,$3}'|while read oldLine; #oldsrv
                			do
                			vaf -v  ${newsrv}| awk -F" " '{ print $2,$3 }'|while read newLine;#newsrv
                			do
                				echo "Comparer la colonne $2 de oldLine avec la colonne $2 de newLine "
                			done
                			
                			done

                voilà l'implémentation que je voudrais. Peut-être que ma solution crains si tu as des idées :)

                -
                Edité par Don_raftapss 10 novembre 2019 à 14:58:29

                • Partager sur Facebook
                • Partager sur Twitter
                  10 novembre 2019 à 15:13:43

                  pour ça, je dois voir la sortie de la commande vaf.

                  là, pour chaque ligne de "vafOld", tu exécutes "vafNew", qui va sortir les mêmes données à chaque fois.
                  ce n'est évidemment pas optimal, puisque l'objectif est de comparer les deux sorties.

                  mais sans la sortie, difficile d'en dire plus.

                  si tu ne fais rien d'autre avec awk, il n'est pas utile; read peux découper une ligne en "colonnes" :

                  # par exemple :
                  echo "a b c d e f g
                  A B C D E F G" | while IFS=' ' read x y z reste; do echo "y: $y; z: $z"; done
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                    10 novembre 2019 à 15:34:56

                    voilà un exemple de la sortie

                    VssVersion:$Header: /HPO/Q2/trame/source/erp/t_shad.dt 9     15/12/17 17:08 Elo $   (vafold)

                    Je veux récuperer /HPO/Q2/trame/source/erp/t_shad.dt 

                    et récuperer 9

                    Après revisite du code ce fichier devrait être  VssVersion:$Header: /HOE/N2/trame/source/erp/t_shad.dt 10 + date du changement(vafnew)

                    Je dispose des 2 fichiers le nouveaux et l'ancien.

                    C'est pas la même sortie car c'est pas les même binaire. Vafnew et le fichier binaire mis a jour

                    Il y a des centaine de ligne ainsi.                                                                                                                                     

                    EDIT

                    Je viens de test avec le read et IFS (je connaissais pas) merci beaucoup. Mais maintenant une question me turlupine quand es qu'il faut utilisé awk?

                    -
                    Edité par Don_raftapss 10 novembre 2019 à 15:57:26

                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 novembre 2019 à 15:59:21

                      je chipote (si peu :) ), mais "une centaine de lignes", ça fait une liste.

                      il est donc bien question de comparer deux listes : diff peut faire ça avec des listes préalablement triées.

                      je récapitule pour qu'on comprenne la même chose :

                      tu as deux fichiers : old et new.
                      chaque fichier (old/new) contient des références à des fichiers *.c et *.h, et *.dt visiblement !
                      la commande vaf affiche la liste de ces références

                      tu veux comparer les listes.

                      on peut imaginer un paste pour lire les listes côte à côte :

                      while IFS='|' read old new
                      do
                         oldAr=( $old )
                         newAr=( $new )
                         test "${oldAr[1]} ${oldAr[2]}" = "${newAr[1]} ${newAr[2]}" || { echo "différence trouvée"; break;}
                      done < <(paste -d '|' <(vaf -v "$oldFile") <(vaf -v "newFile"))

                      je n'ai pas de matériaux pour faire des tests et te proposer un script fonctionnel.
                      c'est pourquoi il faut nous donner les listes de deux fichiers old/new, au moins en MP.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                        10 novembre 2019 à 16:30:19

                        J'ai un script fonctionnel avec le read. Et oui je voulais faire des liste aussi mais le server est un vieux server unix sans list ou alors je n'y arrive pas :D

                        Voici le script

                        vaf -v  ${oldsrv}|while IFS=' ' read oldvss oldChemin oldVersion  oldDate oldNom; #oldsrv
                        			do
                        			vaf -v  ${newsrv}|while IFS=' ' read newvss newChemin newVersion newDate newNom;#newsrv
                        			do
                        				#echo "$oldVersion $newVersion  "
                        				
                        				if [ "$oldChemin" = "$newChemin" ] 
                        				then 
                        				
                        					if [ "$newVersion" != "$oldVersion" ]
                        					then
                        					echo "$oldChemin $oldVersion $newChemin $newVersion  "
                        					fi
                        				
                        			
                        				fi

                        Cela fonctionne et d'ailleurs je t'en remercie.

                        Par contre le script que tu as mis la haut je suis complètement perdu !

                        Tu ne parcour que un seul fichier? Oui parce que en faite les fichier ne se trouve pas spécialement à la même place que dans l'ancien.

                        Que veux dire cette dernière ligne? C'est un genre de double boucle imbriquée? 

                        J'en ai encore à apprendre en bash :D

                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 novembre 2019 à 17:06:54

                          fonctionnel, mais comme je l'ai dit, pour chaque référence dans "old", tu exécutes la commande vaf sur "new".
                          ça va être très long.
                          ça consomme beaucoup de ressources.
                          tu vas avoir des faux positifs, parce que ce qui apparaît au début de "new" ne correspond pas à ce qui est en cours de lecture de "old"

                          quelle est la version de bash sur le serveur ?
                          si il n'y a pas de listes, il n'y a pas non plus de Substitution de processus ( <() ).

                          bon, pas de Substitution de processus, on peut passer par des fichiers temporaires :

                          vaf -v "$oldFile" >/tmp/oldFile
                          vaf -v "$newFile" >/tmp/newFile
                          paste -d '|' /tmp/oldFIle /tmp/newFile | while...

                          et pas de liste :

                          while IFS='|' read old new
                          do
                              oldRef=$(echo "$old" | cut -d ' ' -f1,2) # pour être lisible, mais en peu le faire totalement en bash
                              newRef=$(echo "$new" | cut -d ' ' -f1,2) # > avec quelques Remplacement de paramètres, c'est dans le man.
                              test "$oldRef" = "$newRef" || { ...
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                            10 novembre 2019 à 17:17:44

                            Je ne sais pas comment voir la version du bash. Passer par des fichier temporaire est lent aussi non. Je ne comprend "faux positif" pourquoi? Car je pense que tu as complètement raison mon script ne détecte aucune différence
                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 novembre 2019 à 17:29:43

                              bash --version

                              pour le faux positifs : ton script va comparer toute la sortie de vaf -v "$new" à chaque ligne de vaf -v "$old"
                              en fait tu ne devrais avoir quasiment que des erreurs, car par exemple, la première ligne de "old" peut correspondre à la première ligne de "new",
                              puis le script va continuer à lire "new", et la deuxième ligne ne correspondra pas à la première ligne de "old" toujours en cours, et vice-versa la première ligne re-re-re-relu ne pourra pas correspondre la première ligne de "old" qui n'est plus en cours.
                              pour les fichiers temporaires, il ne seront écrits puis lus qu'une seule fois au lieu d'exécuter autant de fois vaf -v "new" qu'il y a de lignes dans vaf -v "old".
                              c'est beaucoup plus économique.
                              le problème principale des fichiers temporaires c'est les lectures/écritures répétées, qui consomment des ressources et du temps.
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                10 novembre 2019 à 17:53:20

                                bash --version

                                J'avais essayé mais ça marche pas  c'est des serveurs unix par contre les script se lance quand même donc le bash dois être quelque par. J'ai pu remarquer que je n'ai pas besoin de mettre en haut !#bin/bash c'est la toute première fois que je vois ça mais ça marche je sais pas par quel mécanisme

                                Oui c'est vrais à la base je voulais tout mettre dans un tableau(ou liste) le problème c'est que je connais pas la taille de celui-ci et que le terminal me sors une erreur

                                J'aurais que des erreurs si je compare sur les différence mais c'est pas le cas je compare sur le nom du fichier si c'est le même et puis je vérifie si c'est le cas je vérifie le numéro de versionning. Ton script fonctionne que si les fichier sont à la même place non? Car vu que l'on peut rajouter des .c et des .h .dt etc il se peut que par la suite les fichier ne soit pas à la même place. 

                                Désoler pour mes question mais je suis débutant :)

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  10 novembre 2019 à 18:08:04

                                  il faut nous afficher les erreurs.

                                  un script sans shebang est exécuté /bin/sh, qui ne pointe pas obligatoirement vers bash.

                                  attention, un shebang correct est #!/bin/bash : un commentaire, un point d'exclamation et le chemin vers l'interpréteur.

                                  on peut ajouter une commande de tri (sort) avant la redirection vers le fichier temporaire pour qu'ils soient... triés !

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                    10 novembre 2019 à 18:42:38

                                    Donc il est exécuter en sh. Le serveur n'as pas de bash. Donc c'est du shell sh. Je vois du shl mais je connais pas. Je voudrais installer du bash mais cela me semble un peu chaud à faire. 

                                    Ok comment faire pour créer une liste dynamique? Car je ne sais pas combien d'élement sont dans mon fichiers en .sh

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      10 novembre 2019 à 18:48:56

                                      il n'y a pas de liste en /bin/sh.

                                      je ne comprends pas la question.

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                        10 novembre 2019 à 20:41:01

                                        Je n'ai pas le fichier /bin/bash donc shebang ne sers à rien.

                                        Je vais essayer comme tu dis mais pour l'instant je n'ai plus accès au serveur. Je devrais essayer mardi car ferié demain :)

                                        -
                                        Edité par Don_raftapss 10 novembre 2019 à 20:42:02

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          10 novembre 2019 à 21:10:43

                                          ça n'empêche pas de mettre un shebang correspondant au type de shell utilisé (ici /bin/sh), ainsi on saura immédiatement qu'il n'y aura pas de "bashismes", et les formes "archaïques" du script choqueront moins.
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                          Awk et bash

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown