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 :

Utiliser des variable pour générer des tableau et utiliser des variables pour appeler les tableau.


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Points : 6
    Points
    6
    Par défaut Utiliser des variable pour générer des tableau et utiliser des variables pour appeler les tableau.
    Bonjour a tous,

    Que pensez vous de ce code pour arriver à mon but?
    Code : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #!/bin/bash
     
    ###################################
    ##                                                                        
    ##  Parse les fichiers de log présent dans $logdir.     
    ##  Résultat : deux tableaux par fichier,                   
    ##      _hits contenant le nombre d'occurrence d'IP   
    ##      _IP tableau des IPs!                                     
    ##                                                                        
    ###################################
     
     
    logdir="/var/log/apache2/"
     
    ## Pour chaques fichiers access de la semaine précédente
    for logfile in ${logdir}access_*.1
    do
            echo "### Traitement du fichier $logfile ###";
            tabname=`echo "$logfile" | cut -d'.' -f1 | cut -c 25-`;
            switch=1;
            current=0;
            ## Récupérer les IPs, les trier puis en garder une de chaque précédé du nombre d'occurences
            for line in `awk '{print $1}' $logfile | sort | uniq -c`
            do
                    ## Pour le nombre d'occurences, l'ajouter au tableau _hits du fichier en cours.
                    if [ $switch -eq 1 ]; then
                            temp=${tabname}_hits;
                            eval $temp[$current]=$line;
                            ## DEBUG : Test de l'enregistrement.
                            echo $temp[$current] vaut ${!temp[$current]};
                            ((switch++));
                    ## Stocker chaque IP, sur la ligne de même index que son occurence,
                    ## dans le tableau _IP du fichier en cours.
                    else
                            temp=${tabname}_ip;
                            eval $temp[$current]=$line;
                            ## DEBUG : Test de l'enregistrement.
                            echo $temp[$current] vaut ${!temp[$current]};
                            ((switch--));
                            ((current++));
                    fi
            done
    done
    Lorsque je lance mon code, les echo de contrôle ne s'affiche correctement que pour la première ligne de mes tableau.

    Le but est de faire des comparaisons ensuite avec d'autres logs et de m'envoyer un mail sur certains triggers a venir.
    Mais pour l'instant j'en suis là!

    Est-ce une méthode viable?

    Certes plein de logiciels font ce genre de travail d'analyse de logs, comme par exemple AWStats.
    Je ne veux pas alourdir mon Raspberry qui est déjà bien occupé (ancien modèle avec moitié moins de RAM )
    Et surtout, mon but est de m'entrainer.


    Merci d'avance pour vos retours.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 616
    Points : 30 833
    Points
    30 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dixtrian Voir le message
    Et surtout, mon but est de m'entrainer.
    Salut

    A ce que je vois, tu es hyper à l'aise en shell et tu n'as plus (vraiment) besoin de t'entrainer.
    Fais gaffe toutefois aux for line in $(commande) car si commande renvoie des lignes avec espace, le for les coupe en deux. Essaye plutôt de t'orienter vers commande | while read line...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 237
    Points : 13 437
    Points
    13 437
    Par défaut
    Bonjour,

    • Ce ne semble être que de la manipulation de fichiers texte
    • Tu utilises awk dans ton script
    • Tu veux t'entrainer

    Pour ces trois raisons, je te conseille de tout faire dans un script awk.

    Peux-tu donner un exemple de fichier d'entrée et un exemple de sortie?

    Je te donne un exemple de ce qui est possible:
    Code : 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
    17
    18
    19
    20
    21
    22
    23
    24
     
    $ cat compteurIP.txt
    192.168.1.1 blablabla
    192.168.1.1 blablabla
    192.168.1.12 blablabla
    192.168.1.123 blablabla
    192.168.12.1 blablabla
    192.168.1.1 blablabla
    192.168.12.1 blablabla
    #lkdg;sg
    #kqsdjg;k;sdj
    192.168.1.123 blablabla
    192.168.1.1 blablabla
    192.168.1.123 blablabla
    192.168.1.1 blablabla
    192.168.1.12 blablabla
    #:lekjrfg:sekrjgn
    111.222.333.444 jgthgjh
    192.168.1.1 blablabla
    192.168.1.12 blablabla
    192.168.1.12 blablabla
    192.168.1.12 blablabla
    192.168.1.123 blablabla
    192.168.1.123 blablabla


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/awk -f
     
    /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/{
        nbIP[$1]++;
    }
     
    END{
        for (i in nbIP)
    	print i, nbIP[i];
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ compteurIP.awk compteurIP.txt
    192.168.1.12 5
    192.168.12.1 2
    192.168.1.123 5
    192.168.1.1 6
    111.222.333.444 1
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 536
    Points : 19 359
    Points
    19 359
    Par défaut
    parce que je préfère tout faire pour me dispenser d'eval, j'utiliserais un tableau associatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ declare -A aAr
    $ aAr[temp1,0]="ti ti"
    $ aAr[temp1,1]="to to"
    $ aAr[temp1,2]="ta ta"
    $ for i in "${!aAr[@]}"; do a="${i%,*}"; i="${i#*,}"; for aa in "${aAr[$a,$i]}"; do echo "aAr[$a,$i] = ${aAr[$a,$i]}"; done; done
    aAr[temp1,2] = ta ta
    aAr[temp1,1] = to to
    aAr[temp1,0] = ti ti
    mais, je plussoie Flodelarab, quant à l'utilisation de awk, parce que awk sera beaucoup plus rapide sur des gros fichiers.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    [QUOTE]
    • Ce ne semble être que de la manipulation de fichiers texte
    • Tu utilises awk dans ton script
    • Tu veux t'entrainer


    Pour ces trois raisons, je te conseille de tout faire dans un script awk.

    Peux-tu donner un exemple de fichier d'entrée et un exemple de sortie?
    Effectivement on me dit souvent que awk est puissant, il faut que je m'y mette vraiment.

    Voici un fichier log type qui doit être traité (access.log):
    Code : 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
    17
    18
    19
    20
    21
    root@mail /root # tail -20 /var/log/apache2/access.log.1
    113.17.173.11 - - [19/Apr/2014:11:40:18 +0200] "GET / HTTP/1.1" 200 384 "-" "-"
    61.19.42.155 - - [19/Apr/2014:13:59:41 +0200] "GET /phpTest/zologize/axa.php HTTP/1.1" 404 504 "-" "-"
    61.19.42.155 - - [19/Apr/2014:13:59:42 +0200] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 508 "-" "-"
    61.19.42.155 - - [19/Apr/2014:13:59:43 +0200] "GET /pma/scripts/setup.php HTTP/1.1" 404 501 "-" "-"
    61.19.42.155 - - [19/Apr/2014:13:59:44 +0200] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 505 "-" "-"
    116.236.201.246 - - [19/Apr/2014:15:03:24 +0200] "GET /phpTest/zologize/axa.php HTTP/1.1" 404 504 "-" "-"
    116.236.201.246 - - [19/Apr/2014:15:03:25 +0200] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 508 "-" "-"
    116.236.201.246 - - [19/Apr/2014:15:03:26 +0200] "GET /pma/scripts/setup.php HTTP/1.1" 404 501 "-" "-"
    116.236.201.246 - - [19/Apr/2014:15:03:28 +0200] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 505 "-" "-"
    201.239.81.241 - - [19/Apr/2014:15:23:17 +0200] "GET /phpTest/zologize/axa.php HTTP/1.1" 404 504 "-" "-"
    201.239.81.241 - - [19/Apr/2014:15:23:17 +0200] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 508 "-" "-"
    201.239.81.241 - - [19/Apr/2014:15:23:18 +0200] "GET /pma/scripts/setup.php HTTP/1.1" 404 501 "-" "-"
    201.239.81.241 - - [19/Apr/2014:15:23:19 +0200] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 505 "-" "-"
    58.176.171.133 - - [19/Apr/2014:16:10:58 +0200] "GET /phpTest/zologize/axa.php HTTP/1.1" 404 504 "-" "-"
    58.176.171.133 - - [19/Apr/2014:16:10:59 +0200] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 508 "-" "-"
    58.176.171.133 - - [19/Apr/2014:16:11:00 +0200] "GET /pma/scripts/setup.php HTTP/1.1" 404 501 "-" "-"
    58.176.171.133 - - [19/Apr/2014:16:11:00 +0200] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 505 "-" "-"
    146.185.239.100 - - [19/Apr/2014:17:36:34 +0200] "GET http://www.alexa.com/ HTTP/1.1" 200 384 "-" "-"
    113.17.173.11 - - [19/Apr/2014:22:31:21 +0200] "GET / HTTP/1.1" 200 384 "-" "-"
    61.228.24.64 - - [19/Apr/2014:23:43:32 +0200] "CONNECT mx-tw.mail.gm0.yahoodns.net:25 HTTP/1.0" 405 570 "-" "-"
    En sortie, simplement les récurrences de chaque IP et l'IP en question. La façon de les stocker m'importe peu tant que je peux les réutiliser pour la suite.

    A la base, je pensais faire des tableaux ressemblant à ça: nom_vhost[IP]=( "occurrence_access" "occurrence_error" "autre donnée venant de whois" "autre" "etc..." )
    Mais je ne sais pas si on peut en bash mettre un index autre que des chiffres simple (j'avais fait un truc comme ça en perl mais ça date, j'étais encore en cours)

    Je pense mettre en relation les entrées des fichiers error.log de Apache.
    Je verrai ensuite si je balance des whois et selon quelle valeur de déclenchement et autre vérification qui pourront satisfaire ma curiosité sans pour autant être utile
    C'est du fun dans un premier temps.

    parce que je préfère tout faire pour me dispenser d'eval, j'utiliserais un tableau associatif :
    Je crois que tu répond à mon interrogation. Le tableau que j'ai fait en perl devrait être faisable en bash

    ------

    En y réfléchissant, c'est un peu je me prend la tête pour rien à vouloir nommer le tableau avec le nom du vhost car une fois les varaibles "temp" et "tabname" réécrite je ne pourrai pas les récupérer à moins de faire un tableau avec les vhost déjà traité. Je vais repenser mon tableau.

    C'est un peu le bazar dans ma tête, on dira que c'est la faute au travail de nuit le WE

    Ceci dit ma question porte sur le fait de prendre des variables pour composer le nom et l'index des tableaux.
    Est-ce faisable?

    Autrement, ne me donnez pas de réponse sur AWK, la piste que vous donnez m'intéresse et je vais regarder moi même dans un premier temps.


    Merci encore pour vos participation

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 536
    Points : 19 359
    Points
    19 359
    Par défaut
    Ceci dit ma question porte sur le fait de prendre des variables pour composer le nom et l'index des tableaux.
    ça n'en vaut pas la peine.
    oriente-toi vers un langage pour lequel c'est supporté sans avoir à le torturer.
    c'est "naturel" pour Gawk.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    OK c'est noté.

    Je vois déjà 4 dérivé! awk, mawk, gawk, nawk.

    J'ai pas mal de lecture ^^, ça va occuper mes nuit!

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Afin de clore correctement la discution, voici le code sous awk. (et une question bonus )

    Je note que l'utilisation d'un tableau pour nommer une ligne d'un autre tableau est utilisable : "count[ip_list[test]]" dans mon code.
    Je me demande si cela peu engendrer des effets de bord...
    Est-il recommandé de mettre la première valeur dans une variable "ipl_test=ip_list[test]" et d'ensuite l'affecter "count[ipl_test]"?


    Code : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #! /usr/bin/awk -f
     
    {
    ip_list[NR]=$1
    }
    END {
            for (test in ip_list) {
                    switch=0
                    iptest=ip_list[test]
                    for (ipuniq in count) {
                            if (ip_list[test] == ipuniq) {
                                    switch=1
                                    break
                            }
                    }
                    if (switch==1){
                    count[ip_list[test]]=count[ip_list[test]]+1
                    }
                    else {
                    count[ip_list[test]]=1
                    }
            }
            for (ip in count) {
            print count[ip]" ligne contenant "ip
            }
    }

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 536
    Points : 19 359
    Points
    19 359
    Par défaut
    mais pourquoi est-ce si compliqué ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    awk '{ip[$1]++}END{for(i in ip)print ip[i]" ligne(s) contenant "i}' fichier_exemple_du_#5
    4 ligne(s) contenant 201.239.81.241
    4 ligne(s) contenant 58.176.171.133
    1 ligne(s) contenant 61.228.24.64
    2 ligne(s) contenant 113.17.173.11
    1 ligne(s) contenant 146.185.239.100
    4 ligne(s) contenant 61.19.42.155
    4 ligne(s) contenant 116.236.201.246
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 11
    Points : 6
    Points
    6
    Par défaut
    (j'aime me faire mal)

    Bon,peut être parce que je pensais à ajouter les autres données de mes fichiers de log.
    Le tableau serai un ensemble de sous-tableau et les données stockés sont:
    ip, les différents code http rencontré, itération de chaque code http.

    Pour au final afficher pour chaque ip le total de ligne et chaque sous total pour les différents code http.

    Voilà

    A l'instant où j'écris ces lignes mon code est cassé...

    Code : 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #! /usr/bin/awk -f
     
    {
    ip_list[NR]["ip"]=$1
    if ($9 == "\"-\"") {
            ip_list[NR]["httpc"]=$7
    } else { ip_list[NR]["httpc"]=$9 }
    max_NR=NR
    }
    END {
            for (line=1 ; line<=max_NR ; line++) {
                    ip=ip_list[line]["ip"]
                    httpc=ip_list[line]["httpc"]
                    exist=0
    #print "TEST: "line", "ip_list[line]["httpc"]", "ip_list[line]["ip"]
                    for (ipuniq in final) {
                            if (ip == ipuniq) {
                                    exist=1
                                    break
                            }
                    }
                    if (exist==1){
                    final[ip]["count"]++
                    } else { final[ip]["count"]=1 }
                    final[ip]["counthttpc"]++
                    }
            }
            for (ip in final) {
                    print final[ip]["count"]", "ip", "final[ip]["counthttpc"]
            }
    }
    Je continue de chercher à utiliser les différents tableaux de tableaux, fichtre que le temps passe vite!

    PS: je suis passé de mawk à gawk.

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 237
    Points : 13 437
    Points
    13 437
    Par défaut
    Pour au final afficher pour chaque ip le total de ligne et chaque sous total pour les différents code http.
    Les clés sont donc $1, $9 et $10.

    En première intention, dans awk, je ferais trois tableaux différents qui recensent les $1, $9 et $10 possibles, et un tableau principal qui compte chaque sous-cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{effectif[$1"k"$9"k"$10]++;ip[$1]++;http1[$9]++;http2[$10]++;} END{for (i in effectif) print i, effectif[i];print ""; for (i in http1) print i,http1[i];}' monfichier.log
    Ceci n'est qu'un exemple. Tu as tout pour reconstruire l'indice du tableau principal et faire tous les regroupements idoines.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 09/09/2009, 12h20
  2. Réponses: 0
    Dernier message: 14/09/2008, 19h35
  3. Réponses: 0
    Dernier message: 14/09/2008, 19h30
  4. Utilisation de tables pivots pour générer des graphes
    Par acraenin dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 23/10/2007, 12h19
  5. [JFOR][RTF]Utilisation de jfor pour générer des RTF
    Par pistache42 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 28/04/2006, 10h23

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