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 :

Expression régulière qui engloberait tous les cas


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 157
    Par défaut Expression régulière qui engloberait tous les cas
    Bonjour,

    Cette fonction a pour but de copier dans le répertoire /$contexte/diffusion/tmp/ une portion de log horodatée. Les variables d'entrée sont notifiées dans un fichier.
    Dans liste il peut y avoir plusieurs lignes de ce type.
    $contexte $instance $heure_debut $heure_fin $type_log $AAAA_MM_JJ $nom_serveur
    Le script peut donc parser plusieurs lignes.

    J'ai 2 répertoires différents

    Dans ce répertoire /$contexte/log/tech/jonas/jonas$instance /
    $nom_log peut prendre les noms suivants :
    $type_log.log ( log courant)
    $type_log.log.$AAAA_MM_JJ.001 (log courant splitté par taille )
    $type_log.log.$AAAA_MM_JJ.002
    $type_log.log.$AAAA_MM_JJ.002
    etc.
    $type_log.log.$AAAA_MM_JJ.tar.gz (log de 1 journée archivé à J+1)

    A j+2 les tar.gz sont déplacés dans ce répertoire /$contexte/archivage/$instance /
    Ici $nom_log peut prendre le nom suivant :
    $type_log.log.$AAAA_MM_JJ.tar.gz

    Concrètement les variables peuvent renvoyer :
    server.log
    server.log.2013-07-31.001
    server.log.2013-07-29.tar.gz

    La fonction fonctionne sauf pour le cas qui prend en compte la date du jour c'est à dire quand les log courants se terminent par 001 002 etc. Les logs courants server.log et server.log.2013-07-29.tar.gz quant à eux fonctionnent.


    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    function grep_hour
    {
            # Declarartion des variables
            contexte=$(echo $1 |tr [:lower:] [:upper:])
            instance=$(echo $2 |tr [:lower:] [:upper:])
            heure_debut=$3
            heure_fin=$4
            type_log=$5
            AAAA_MM_JJ=$6
            date_du_jour=$(echo $(date '+%Y/%m/%d') | sed 's/\//-/g') # Date du jour au format AAAA-MM-JJ
     
            # Traitement particulier du server.log
            if [ ! "$date_du_jour" = "$AAAA_MM_JJ" ]; then
                    nom_log="$type_log*.log.$AAAA_MM_JJ.tar*"
     
            else
                   nom_log="$type_log.log"
     
                    fi
                    if [ "$server" == "$7" ]; then
                            ssh=""
                    else
                            ssh="ssh -n $7"
     
                           $ssh find /$contexte/archivage/$instance/ /$contexte/log/tech/jonas/jonas$instance/ -type f -iname "$nom_log"  2> /dev/null |\
     
                     { while read FICHIER; do # Debut de la boucle while
                            REPERTOIRE=$(dirname "${FICHIER}")
                            nom_de_log=$(basename "${FICHIER}")
                                    if [ "$date_du_jour" = "$AAAA_MM_JJ" ]; then
                                            DATE=$(echo $(date '+%d/%m/%Y'))
                                    else
                                            DATE=$(echo $nom_de_log | sed 's#.*\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\).*#\3/\2/\1#') # Extraction de la date du nom de fichier
                                    fi
                            newdate=$(echo $DATE | sed 's/\//-/g') # Formatage de AAAA/MM/JJ en JJ-MM-AAA
                                    # Choix de la commande cat ou gunzip -c suivant l'extension
                                    if [[ "$nom_de_log" =~ .gz$ ]]
                                            then z_cat="gunzip -c"
                                            else z_cat=cat
                                    fi
                            # Bornage horaire du log
                            $ssh $z_cat "$REPERTOIRE/$nom_de_log" | awk -F"[/ \\\][]" -v S="$DATE $heure_debut" -v E="$DATE $heure_fin" ' #Exemple -v S="10/12/2012 10:15" -v E="10/12/2012 11:30"
                                    function dcmp(b) { #Parsing du log
                                    if($4>b[3])return  1; # On compare d abord les annees ($4 et b[3]).
                                    if($4<b[3])return -1; # Si elles sont differentes, on renvoie 1 ou -1
                                    if($3>b[2])return  1; # Si elles sont egales, on compare les mois ($3 et b[2])
                                    if($3<b[2])return -1; # S ils sont differents, on renvoie 1 ou -1
                                    if($2>b[1])return  1; # S ils sont egaux, on compare les jours ($2 et b[1])
                                    if($2<b[1])return -1; # S ils sont differents, on renvoie 1 ou -1
                                    if($5>b[4])return  1; # S ils sont egaux, on compare les heures ($5 et b[4])
                                    if($5<b[4])return -1; # Si elles sont differentes, on renvoie 1 ou -1
                                    return 0; # Si elles sont egales, on renvoie 0
                                            }
                                            BEGIN{split(S, ds, "[/ ]"); split(E, de, "[/ ]") }
                                            /^[[][0-9][0-9]\/[0-1][0-9]\/[[0-9][0-9][0-9][0-9] / { #Fait correspondre les lignes qui commencent par deux chiffres suivis par une barre oblique puis 0 ou 1 puis des chiffres puis un slash et enfin 4 chiffres (c est a*dire 1 ligne qui commence par une date au format 99/99/9999).
                                            if(s&&dcmp(de)>=0) {print; exit} #si la date_de_depart deja trouvee (s est non vide / zero) et ate dans la ligne courante> = date_de_fin alors editee ligne actuelle et arreter le traitement.
                                            if(!s&&dcmp(ds)<=0) {f=x;w=1}#si la date_de_debut n est pas encore trouvee (s nest pas initialisee) et la date dans la ligne actuelle <= date_de_debut, contenu vierge de la variable f et initialiser la variable w. f est un tampon qui contient toutes les lignes trouvees a*partir du debut du document.
                                            if(!s&&dcmp(ds)>=0) {printf "%s",f; f=x; s=1 } #si les variables w et s ne sont pas initialisees coller la ligne courante dans le tampon de f. #si les variables w et s ne sont pas initialisees, coller la ligne courante dans le tampon de f.
                                            }
                                            !w&&!s {f=f $0 "\n"} # si le variable s n est pas initialisee editer la ligne courante.
                                            s' > "/$contexte/diffusion/tmp/$7.$instance.$newdate.${heure_debut}H-${heure_fin}H.log"
                            echo "Le log $7.$instance.$newdateH${heure_debut}H-${heure_fin}H.log se trouve dans /$contexte/diffusion/tmp/"
                            OK=1; # Test fichier present
                            done;
                            [ "$OK" != "1" ] && echo -e "Il n'y a pas de log a la date du "$AAAA_MM_JJ""; # Test fichier absent
     
                    } # Fin de la boucle while
    fi
    } # Fin de la fonction grep_hour
     
    # Comportement du script suivant le nombre de  parametres
    case $# in
                   1)      if [ ! -f "$1" ]; then
                            echo -e "# Alimenter les 7 variables ci-dessous \n# contexte instance heure_debut heure_fin type_log date \n # "\
                            > $1 && echo -e "Merci de remplir le fichier "$1" :\nUne fois rempli, taper $(basename $0) "$1"\n appuyer sur ENTREE"
                            read -p ""
                            echo $REPLY vi $1
                            else
                            while read CONTEXTE INSTANCE HH_debut HH_fin type_log DATE
                            do
                            [ "${CONTEXTE:0:1}" = "#" ] && continue # Ignore les commentaires
                            [ -z "$CONTEXTE" ] && continue # Ignore les lignes vierges
                                    grep_hour $CONTEXTE $INSTANCE $HH_debut $HH_fin $type_log $DATE # Traitement par la fonction grep_hour
                            done < $1
                    fi
                    ;;
            7)    grep_hour $1 $2 $3 $4 $5 $6 $7 # Traitement des parametres par la fonction grep_hour
                    ;;
            8)      echo -e "# Alimenter les 7 variables ci-dessous\n# contexte instance heure_debut heure_fin date" > $1          # creation du fichier $1 au choix
                    echo $2 $3 $4 $5 $6 $7 $8 >> "$1"                  # concatenation des variables dans $1
                                    grep -v '^#' "$1" | # Omet les commentaires
                                    while read CONTEXTE INSTANCE HH_debut HH_fin type_log DATE nom_serveur # Parse les parametres
                                    do grep_hour $CONTEXTE $INSTANCE $HH_debut $HH_fin $type_log $DATE $nom_serveur # Traitement des parametres par la fonction grep_hour
                                    done
                    ;;
    esac

    Je ne suis pas arrivé à trouver une expression régulière qui engloberait tous les cas.

    je vous remercie de votre aide.

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Faut-il que l'on comprenne tout ton problème pour t'aider?

    Peux-tu simplifier ton problème?

    Quelle expression régulière cherches-tu?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 157
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Faut-il que l'on comprenne tout ton problème pour t'aider?

    Peux-tu simplifier ton problème?

    Quelle expression régulière cherches-tu?
    Merci pour ton aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # Traitement particulier du server.log
            if [ ! "$date_du_jour" = "$AAAA_MM_JJ" ]; then
                    nom_log="$type_log*.log.$AAAA_MM_JJ.tar*"
     
            else
                   nom_log="$type_log.log"
    La partie rouge correspond aux logs du jour qui prennent les formes suivantes, si $type_log est égale à server,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    server.log
    server.log.2013-08-06.001
    server.log.2013-08-06.002
    server.log.2013-08-06.003
    et ainsi de suite.
    Le problème serait donc de trouver une forme régulière pour ces formes.

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

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

    • Que c'est bizarre d'archiver à J+1 et déplacer à J+2. Soit on archive, soit on garde sous le coude, mais pas les deux.
    • Ce n'est pas une expression régulière mais un nom de fichier avec des caractères joker.
    • Médite la console ci dessous:
      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
      $ ls -1
      bozo.log
      bozo.log.2013-08-06.001
      bozo.log.2013-08-06.002
      bozo.log.2013-08-06.003
      bozo.log.2013-08-06.tar.gz
      server.log
      server.log.2013-08-05.001
      server.log.2013-08-05.002
      server.log.2013-08-05.003
      server.log.2013-08-06.001
      server.log.2013-08-06.002
      server.log.2013-08-06.003
      server.log.2013-08-06.tar.gz
      $ shopt -s extglob
      $ monhost=server
      $ madate=2013-08-06
      $ ls -1 $monhost.log?(.$madate*)
      server.log
      server.log.2013-08-06.001
      server.log.2013-08-06.002
      server.log.2013-08-06.003
      server.log.2013-08-06.tar.gz
      $ shopt -u extglob
      $ ls -1 $monhost.log?(.$madate*)
      bash: Erreur de syntaxe près du symbole inattendu « ( »
      Pour plus d'inforamtions man bash puis rechercher la chaine extglob.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 157
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Bonjour

    • Que c'est bizarre d'archiver à J+1 et déplacer à J+2. Soit on archive, soit on garde sous le coude, mais pas les deux.
    • Ce n'est pas une expression régulière mais un nom de fichier avec des caractères joker.
    • Médite la console ci dessous:
      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
      $ ls -1
      bozo.log
      bozo.log.2013-08-06.001
      bozo.log.2013-08-06.002
      bozo.log.2013-08-06.003
      bozo.log.2013-08-06.tar.gz
      server.log
      server.log.2013-08-05.001
      server.log.2013-08-05.002
      server.log.2013-08-05.003
      server.log.2013-08-06.001
      server.log.2013-08-06.002
      server.log.2013-08-06.003
      server.log.2013-08-06.tar.gz
      $ shopt -s extglob
      $ monhost=server
      $ madate=2013-08-06
      $ ls -1 $monhost.log?(.$madate*)
      server.log
      server.log.2013-08-06.001
      server.log.2013-08-06.002
      server.log.2013-08-06.003
      server.log.2013-08-06.tar.gz
      $ shopt -u extglob
      $ ls -1 $monhost.log?(.$madate*)
      bash: Erreur de syntaxe près du symbole inattendu « ( »
      Pour plus d'inforamtions man bash puis rechercher la chaine extglob.
    J'ai modifié ma fonction comme tu l'as préconisé. En rouge et dans la commande find.
    ça ne marche pas, j'ai le message "Il n'y a pas de log a la date du 2013-08-06" alors que j'ai actuellement ces 3 logs.

    server.log
    server.log.2013-08-06.002
    server.log.2013-08-06.003

    Peux-tu m'éclairer ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Declarartion des variables
            contexte=$(echo $1 |tr [:lower:] [:upper:])
            instance=$(echo $2 |tr [:lower:] [:upper:])
            heure_debut=$3
            heure_fin=$4
            type_log=$5
            AAAA_MM_JJ=$6
            date_du_jour=$(echo $(date '+%Y/%m/%d') | sed 's/\//-/g') # Date du jour au format AAAA-MM-JJ
            shopt -s extglob
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ssh find /$contexte/archivage/$instance/ /$contexte/log/tech/jonas/jonas$instance/ -type f -iname "$nom_log.log?(.$AAAA_MM_JJ*)" 2> /dev/null

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Dans une commande 'find', je ne sais pas.
    Si tu utilises 'ls' dans un script, N_BaH va hurler.
    Mais quand N_BaH aura fini de hurler, il pourra nous dire comment faire avec 'find' une chose si facile à faire avec 'ls'

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par amazigh42 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            date_du_jour=$(echo $(date '+%Y/%m/%d') | sed 's/\//-/g') # Date du jour au format AAAA-MM-JJ
    Euh...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ date '+%Y-%m-%d'
    2013-08-06
    Ou plus simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ date '+%F'
    2013-08-06

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 157
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Salut,



    Euh...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ date '+%Y-%m-%d'
    2013-08-06
    Ou plus simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ date '+%F'
    2013-08-06
    Effectivement, j'ai pris un canon pour tuer une mouche
    Merci

Discussions similaires

  1. [RegEx] Expression régulière qui supprime les []
    Par ipeteivince dans le forum Langage
    Réponses: 4
    Dernier message: 24/11/2010, 14h02
  2. [REGEX] expression régulière qui match tout les nombres sauf un
    Par neuromencien dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 28/05/2008, 08h21
  3. Macro excel qui ferme tous les fichiers .xls
    Par max2245 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 10/01/2006, 20h21
  4. Formulaire qui contient tous les champs d'une table
    Par cakeby dans le forum Access
    Réponses: 2
    Dernier message: 09/01/2006, 09h22
  5. Utilisateurs qui ont tous les droits.
    Par seal3 dans le forum Shell et commandes GNU
    Réponses: 14
    Dernier message: 15/02/2005, 20h41

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