Shell expressions régulières again

Slt à tous.
Une fois encore j'ai des problèmes avec les expressions régulières.
Je reçois ds mon programme shell deux paramètres dates du genre 0601 et 0630 (du 01 juin au 30juin).
Je fais un sed sur un fichier histoire de trver les lignes ki contiennent des dates comprises entre ces deux dates.
Mon fichier est de la forme:
http://cjoint.com/data/iqopJC7GXy.htm
j'ai essayé un truc de la forme sed -e "/^blablabla[$2-$3]/!d fich

j'ai un message d'erreur du genre "sed invalide range end"

--
Lookouster.partager.cècool!!
Configuration: Windows XP
Internet Explorer 6.0

20 réponses

  • Votes
  • Date
  • Date décroissante
Résumé de la discussion

Le problème porte sur l’extraction des lignes dont les dates au format MMJJ (par exemple 0601 à 0630) se situent entre deux bornes, avec sed qui renvoie l’erreur « invalid range end ». Plusieurs propositions retiennent une expression régulière pour filtrer les lignes entre les jours 01 et 30, par exemple sed '/06\([0-2][0-9]\|30\)/!d' ou sed '/06\([0-2][0-9]\|30\)/d'. Des échanges signalent aussi des difficultés selon l’environnement (HP-UX ou Windows) et recommandent de tester sur un fichier plus conséquent pour comprendre les comportements. D’autres pistes suggèrent d’adapter les variables à la syntaxe employée ou d’envisager des approches alternatives comme awk pour une comparaison numérique plus fiable dans certains cas.

Bobot (l’IA à votre service)
  1. Modérateur
    Salut,

    tu n'as pas compris les classes de caractères je vois
    pour avoir une date comprise entre 01 et 30 juin tu peux écrire quelque chose de genre
    lami20j@deb:~$ cat Desktop/boutfich.htm
    3226220205011533372001      97983928        00008020000028000003       0
    3227220206011533373001      95572928        00000020400000000000       0
    322802020601153337601       21383551        00011010000042000001       0
    32290102061015333821313480  20223249        00003020001031000032       0
    3230220206111533372001      97387721        00008020000013000002       0
    3231220206211533374010      90010174        00008020000043000005       0
    3232220206291533374010      90933877        00008020000006000001       0
    3233220206301533372001      97237383        00000020400000000000       0
    323402020630153338701       80100000        00021010002826000010       0
    3235220207011533382001      97136268        00000020400000000000       0
    3236220207011533383001      90038265        00000020400000000000       0
    lami20j@deb:~$ cat Desktop/boutfich.htm | sed '/06\([0-2][0-9]\|30\)/!d'
    3227220206011533373001      95572928        00000020400000000000       0
    322802020601153337601       21383551        00011010000042000001       0
    32290102061015333821313480  20223249        00003020001031000032       0
    3230220206111533372001      97387721        00008020000013000002       0
    3231220206211533374010      90010174        00008020000043000005       0
    3232220206291533374010      90933877        00008020000006000001       0
    3233220206301533372001      97237383        00000020400000000000       0
    323402020630153338701       80100000        00021010002826000010       0
    lami20j@deb:~$ cat Desktop/boutfich.htm | sed '/06\([0-2][0-9]\|30\)/d'
    3226220205011533372001      97983928        00008020000028000003       0
    3235220207011533382001      97136268        00000020400000000000       0
    3236220207011533383001      90038265        00000020400000000000       0
    lami20j@deb:~$
    
    --
    lami20j
    1. T'as pas compris ma question au fait!!
      Ds mon cas, c'est ke la date est passée par variable!! dc ds l'intervalle à faire fugurer dans l'expression régulière il faut laisser aparaitre une variable.
      Merci
      1. Modérateur
        Si il a compris la question !

        C'est à toi d'adapter tes variables en fonction de la syntaxe que t'a donnée lami20j !
        1. mon problème est de savoir comment extraire les lignes ou les dates sont comprises entre
          13 janvier et 28 spetmebre par exemple.
          les jours et mois peuvent varier!!!
          et c ke j'aimerais savoir si ya pas un truc du genre
          sed "/[$mois1-$mois2][$jour1-$jour2]/....
          1. Modérateur
            Salut,

            comme je l'ai déjà dit, tu n'as pas compris les classes de caractères

            entre les crochetschaque caractère est lu tel quel sauf certaines exceptions
            par exemple le point à l'intérieur d'une classe de caractères est lu comme un caractère litérral donc il n'est plus un métacaractère de la regex
            Une classe de caractère c'est un mini environnement où les variables ne peuvent pas être exploitées

            en revanche on peut bidouiller pour utiliser des variables mais pas de la manière que tu veux
            je n'ai pas le temps pour l'instant, mais si jamais tu ne trouves pas la réponse jusqu'à ce soir
            je vais essayer de te donner une solution :-)
            1. Hello,

              Je n'ai pas trouve la solution en shell/sed mais je l'ai trouve en awk.
              Le format du fichier texte est fortement ameliorable... Pourquoi ne pas reserver une colonne pour la date?
              Que se passe-t-il lorsque l'on change d'annee?

              #!/bin/awk
              # Filename: test.awk
              # Usage: awk -f test.awk -v start=MMDD stop=MMDD boutfichier.txt
              $1 ~ /[0-9]*/ {
              # D'apres le format du fichier
              # je suppose que la date commence toujours au neuvieme caractere.
              date = substr($0, 9, 4);
              if (date >= start && date <= stop) {
              print $0;
              }
              }
              1. bonsoir

                je cherche de laide sur awk comment avoir en méme temp dans la méme command un cpu status et last restart server
                cpu statuts :/usr/sbin/psrinfo
                als101
                --------
                0 on-line since 03/22/2007 01:50:34
                1 on-line since 03/22/2007 01:50:34
                2 on-line since 03/22/2007 01:50:34
                3 on-line since 03/22/2007 01:50:34

                et last restart server : uptime | awk '{print "============>>"$3" " " "$4}'

                als101
                --------
                ============>>622 days,

                je veut les combiné
              2. Modérateur
                @carpathiaSalut,

                Essaye ça :
                ((/usr/sbin/psrinfo | head -1)  && uptime) | sed 'N;s/\n/ /' | awk...
                Je te laisse adapter la syntaxe de "awk" en fonction de la nouvelle sortie ;-))
              3. @jipicybonsoir

                jai le resultat :

                als101
                --------
                ============>>-line since
                ============>>623 days,

                avec cette command :

                ((/usr/sbin/psrinfo | head -1) && uptime) | sed 'N;s/\n/ /'|awk '{print "============>>"$3" " " "$4}'
              4. Modérateur
                @jipicyBon alors procédons par ordre...

                Affiche le résultat de chacune des commandes suivantes :
                /usr/sbin/psrinfo
                /usr/sbin/psrinfo | head -1
                uptime
                /usr/sbin/psrinfo | head -1 && uptime
                (/usr/sbin/psrinfo | head -1 && uptime) | sed 'N;s/\n/ /'
                Fais un copier/coller exact de la commande tapée dans un terminal et de son résultat affiché. Merci.
            2. Modérateur
              Salut,
              #!/bin/bash
              
              echo -e "Entrez mois : \c"
              read mois
              echo -e "Entrez jour debut : \c"
              read jdeb
              echo -e "Entrez jour fin : \c"
              read jfin
              
              while read ligne
              do
              m=${ligne:8:2}
              j=${ligne:10:2}
              
              if  [ $m -eq $m -a $j -ge $jdeb -a $j -le $jfin ]
                then
                 echo $ligne
               fi
              done < aaa
              lami20j@debian:~$ cat aaa
              322802020501153337601
              322802020601153337601
              322802020601153337601
              322802020602153337601
              322802020603153337601
              322802020610153337601
              322802020610153337601
              322802020610153337601
              322802020610153337601
              322802020615153337601
              322802020617153337601
              322802020630153337601
              322802020701153337601
              lami20j@debian:~$ sh ccm.sh
              Entrez mois : 06
              Entrez jour debut : 9
              Entrez jour fin : 22
              322802020610153337601
              322802020610153337601
              322802020610153337601
              322802020610153337601
              322802020615153337601
              322802020617153337601
              lami20j@debian:~$
              1. Merci pour les efforts mais 7 ligne
                Cette ligne j'y vois k dalle!!
                if [ $m -eq $m -a $j -ge $jdeb -a $j -le $jfin ]
                1. Modérateur
                  ce n'est qu'un exemple
                  tu n'as qu'as les tester sur un fichier plus grand

                  je ne vois pas où est le problème
                  tu veux obtenir les lignes entre 2 dates si j'ai bien compris

                  soit un peu plus cohérent dans tes messages, et pas de SMS s'il te plaît

                  affiche ce que tu tapes ainsi que le fichier
                  et on verra ce que ne marche pas
                  1. non, Xcuses pour l'écriture.
                    Ma préoccupation est qu'au fait je veux comprendre cette syntaxe i mean que fait-elle??
                    if [ $m -eq $m -a $j -ge $jdeb -a $j -le $jfin ]
                    1. Modérateur
                      if  [ $m -eq $mois -a $j -ge $jdeb -a $j -le $jfin ]
                      j'ai fait une erreur (correction en gras), désolé

                      SI $m (m c'est le mois dans ta chaine) est égal avec $mois (ce que tu saisi) AND $j (j c'est le jour dans la chaine) est plus grand ou égal que $jdeb (ta saisie) AND le même $j est plus petit ou égal que $jfin (ta saisie)

                      ALORS
                      alors affiche la ligne

                      IS (END SI)
                      1. Modérateur
                        Salut,

                        À mon avis y'a un ch'tit bug dans la syntaxe, il faut lire plutôt :
                        if [ $m -eq $mois -a $j -ge $jdeb -a $j -le $jfin ]
                        Ce qui revient à dire :

                        if = si
                        $m = la variable $m (contenant le 8ème et 9ème caractère)
                        -eq = est égale
                        $mois = à la variable $mois (premier "read" du script)
                        -a = ET
                        $j = la variable $j (contenant le 10ème et 11ème caractère)
                        -ge = est plus grande que
                        $jdeb = la variable $jdeb (2ème "read" du script)
                        -a = ET
                        $j = la variable $j (contenant le 10ème et 11ème caractère)
                        -le = est plus petite que
                        $jfin = la variable $jfin (3ème "read" du script)

                        ;-))
                        1. Modérateur
                          Salut,

                          À mon avis
                          ton avis est juste :-)
                        2. Modérateur
                          @lami20jJe suis de ton avis alors ;-))

                          PS. Configuration: Windows XP C'est quoi ça ??? :-DD
                        3. Modérateur
                          @jipicyConfiguration: Windows XP C'est quoi ça ??? :-DD
                          Je suis au boulot :-D

                          Toute fois, ça m'a permis de beta testeurs de ccm 2 0#43
                      2. je ne vois pas la différence entre vos deux syntaxes lol.
                        C'était le -a ki me troublait. j'aurais moi mis chacune des conditions ds son crochet avec des and en séparateur.
                        Merci pour tout!!
                        1. Modérateur
                          Le -a c'est pour AND
                          if [ test1 AND test2 AND test3 ]
                          --
                          lami20j
                          1. Dites, j'ai un autre problème mais sous HP-UX. Je multiplie une variable par 17 c'est à dire
                            mont=$(($ntba*17))

                            sous linux (knoppix) pas d blems.
                            Mais sur HP-UX il me crée tous les problèmes du monde lol.
                            Vous aurez une idée d comment faire ça autrement?
                            1. Modérateur
                              [tmpfs]$ echo $var
                              100
                              
                              [tmpfs]$ new_var=$(echo "$var * 17" | bc)
                              
                              [tmpfs]$ echo $new_var
                              1700
                              
                              [tmpfs]$
                              ;-))
                              1. AH tu fais appel à beautifull calculator!!!
                                okay j vais essayer. C'est dur comme on peut galérer!!
                                1. Nop ça prend pas!!
                                  Merci kan même
                                  1. Modérateur
                                    Essaie comme ça alors :
                                    new_var=$(expr $var \* 17)
                                    et arrête le SEUMEUSEU merci !
                                2. Modérateur
                                  Mais sur HP-UX il me crée tous les problèmes du monde lol.
                                  Et, si tu nous donnes un peu ce que tu as comme résultat, au moins pour voir tous les problèmes du monde :-))
                                  1. lol!!
                                    j'ai kitté la machine en kestion
                                    mais c'étaitt un truc dans le genre l'expression * n'était pas reconnue. Mais anyway, j n riske pas d revenir sous HP-UX de sitôt.
                                    Thx