IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

[awk] Afficher le FILENAME une fois par fichier puis afficher le mot suivant des occurrences dans le contenu


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien réseaux et télécoms
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien réseaux et télécoms
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut [awk] Afficher le FILENAME une fois par fichier puis afficher le mot suivant des occurrences dans le contenu
    Bonjour !

    J'ai un dossier titi contenant plusieurs dossiers nommés toto_tata. Chaque dossier contient (entre autres) un fichier backtrace.log

    Je souhaite créer un fichier .csv avec une seule ligne par fichier backtrace.log qui devrait ressembler a ça:

    toto1;tata1;mot suivant l'occurrence1;mot suivant l'occurrence2;mot suivant l'occurrence3
    toto2;tata2;mot suivant l'occurrence1;mot suivant l'occurrence2;mot suivant l'occurrence3
    etc...
    (autant de lignes que de fichiers backtrace.log - pas de chiffre après toto ou tata en vrai )

    Pour le moment ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for fn in /CHEMIN/VERS/titi/*/*.log; do
    awk -F'[ \\+]' '{NR==1; OFS=";"
      for (i=1;i<=NF;i++) {
            if ($i=="RIP:"){print FILENAME,$(i+1)>>"/CHEMIN/VERS/titi/export.csv"};
    		}}' $fn
    done
    ...me donne ça:
    CHEMIN/VERS/titi/toto_tata1;mot suivant l'occurrence1
    CHEMIN/VERS/titi/toto_tata1;mot suivant l'occurrence2
    CHEMIN/VERS/titi/toto_tata1;mot suivant l'occurrence3
    CHEMIN/VERS/titi/toto_tata2;mot suivant l'occurrence1
    CHEMIN/VERS/titi/toto_tata2;mot suivant l'occurrence2
    CHEMIN/VERS/titi/toto_tata2;mot suivant l'occurrence3
    ...

    (pas de chiffre après toto_tata en vrai )

    ...et ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for fn in /GNOC/Kernel_panic/Imports/*/*.log; do
    printf $fn | awk -F'[_/]' '{print $(NF-2)";"$(NF-1)}'
    done
    me donne:

    toto1;tata1
    toto2;tata2
    etc...

    Sinon avec print ARGV[1] ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for fn in /CHEMIN/VERS/titi/*/*.log; do
    awk 'BEGIN{ORS=";"; print ARGV[1]}' $fn
    done
    ...me donne:
    /CHEMIN/VERS/titi/toto_tata1;/CHEMIN/VERS/titi/toto_tata2;/CHEMIN/VERS/titi/toto_tata3;etc...

    J'ai essayé de mettre un print ARG[1] avant la boucle de la commande awk mais j'arrive pas.

    (Vous avez compris, je suis un newbie!)

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 694
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    Bonjour,

    la boucle shell est inutile, et par substitution successives, tu dois pouvoir retrouver le nom du répertoire au-dessus du backtrace en traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{...}' /chemin/titi/*/backtrace.log
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre averti
    Homme Profil pro
    Technicien réseaux et télécoms
    Inscrit en
    Octobre 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien réseaux et télécoms
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2015
    Messages : 23
    Par défaut
    Ah oui effectivement la boucle en bash est pas nécessaire !

    Comment re-traiter un print FILENAME sans utiliser de tube comme dans cet exemple ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for fn in /GNOC/Kernel_panic/Imports/*/*.log; do
    printf $fn | awk -F'[_/]' '{print $(NF-2)";"$(NF-1)}'
    done

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 694
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 694
    Par défaut
    je ne comprends pas la question.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 298
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 298
    Par défaut
    Bonjour

    Est-ce qu'on peut avoir le vrai but réel ? Non, parce que, là, j'ai l'impression que tu réinventes grep.

    Soit un fichier rip0.txt :
    blablabla RIP blablabla encore RIP
    et puis RIPattaché avant attachéRIPaumilieu et aprèsRIP
    et puis RIP
    et enfin
    RIP
    
    Et des fichiers dérivés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for ((i=1;i<6;i++));do sed "${i}d" rip0.txt > "rip${i}.txt";done
    La commande pour compter le nombre de RIP dans chaque fichier est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ grep -Ho RIP rip* | uniq -c
          7 rip0.txt:RIP
          5 rip1.txt:RIP
          4 rip2.txt:RIP
          6 rip3.txt:RIP
          7 rip4.txt:RIP
          6 rip5.txt:RIP
    Et la commande pour compter le nombre de mot RIP dans chaque fichier est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ grep -Ho '\<RIP\>' rip* | uniq -c                                                                                                                                                                                                                             
          4 rip0.txt:RIP
          2 rip1.txt:RIP
          4 rip2.txt:RIP
          3 rip3.txt:RIP
          4 rip4.txt:RIP
          3 rip5.txt:RIP
    Ce qui est bien plus simple que le code du début de discussion.

  6. #6
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    Citation Envoyé par guenoel Voir le message
    Je souhaite créer un fichier .csv avec une seule ligne par fichier backtrace.log (...)
    c'est pas clair du tout, par exemple j'ai du mal à comprendre à quoi correspondent totoX et tataY si il n'est question que des fichiers nommés "backtrace.log"
    par ailleurs :

    Citation Envoyé par guenoel Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (...) /GNOC/Kernel_panic/Imports/*/*.log (...)
    on en déduit assez simplement que les logs en question sont des backtraces de kernel panic (et donc les RIP ce sont les adresses 64b où le kernel est censé s'être vautré)

    or dans ces logs on trouve des lignes avec l'occurrence "RIP:" qui peuvent avoir cette tête là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [exception RIP: intel_idle+213]
    [exception RIP: unknown or invalid address]
    RIP: 0010:[<ffffffff81318bc4>] [<ffffffff81318bc4>]
    RIP: ffffffff816ab6a5  RSP: ffff8b00fb16fe20  RFLAGS: 00000046
    pas évident dans ces conditions de savoir ce que tu cherches précisément à extraire

    alors de ce que j'ai compris/extrapolé, et en admettant :
    • que totoX corresponde au dernier répertoire (le sous-répertoire dans Imports/ donc)
    • que tataX corresponde au nom du fichier de log, sans l'extension (donc "backtrace" dans le cas de backtrace.log)
    • qu'il s'agisse pour chaque occurrence de RIP: de récupérer l'adresse 64b hexa qui suit et les concaténer afin de ne former qu'une seule ligne par fichier de log du type:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      totoX;tataY;ffffffff816ab6a5;ffffffff81318bc4;...
    • que tu utilises GNU Awk (sinon Samar Shrapa)


    on peut envisager un bout de code du genre :
    Code script.awk : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /RIP: [0-9a-f]{16}/ {             # specifique GNU Awk (regex quantifier)
       for (i = 1; i < NF; i++) {
          if ($i == "RIP:") {
             line = line ";" $(i+1)
             break
          }
       }
    }
     
    ENDFILE {                        # specifique GNU Awk
       n = split(FILENAME, tab, "/")
       gsub(/\.log/, "", tab[n])     # on enleve l extension .log du nom de fichier
       prefix = tab[n-1] ";" tab[n]  # prefixe de la forme "sous-repertoire;fichier"
       print prefix line
       line = ""
    }

    qu'on pourra invoquer via gawk -f script.awk /GNOC/Kernel_panic/Imports/*/*.log.

Discussions similaires

  1. fichier qui s'écrase une fois par semaine
    Par sam01 dans le forum Langage
    Réponses: 0
    Dernier message: 20/11/2015, 23h54
  2. Afficher une div une fois par jour
    Par stanux24 dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 30/11/2011, 00h29
  3. Réduction fichier log une fois par mois
    Par ozzy75 dans le forum Administration
    Réponses: 4
    Dernier message: 28/01/2009, 10h02
  4. Exécuter un script, une fois par jour
    Par Poussy-Puce dans le forum ASP
    Réponses: 1
    Dernier message: 19/10/2006, 17h55
  5. [Sécurité] Refuser une URL par fichier .htaccess
    Par tom06440 dans le forum Langage
    Réponses: 7
    Dernier message: 28/11/2005, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo