Problème de formatage de date avec awk strftime

Bonjour,

Je travail avec la version 20 de Mint.

Voici ma ligne de commande :
awk -F"," '{ print strftime("%Y-%m-%d %H:%M:00 ",$1),$2,$3 }' TestDate.txt

où
$1
correspond à :
 '01-Jun-18 12:00:00 AM EDT'
.

Le résultat de la commande donne :
1969-12-31 19:00:00
pour tous les enregistrements de mon fichier. Si j'utilise
systime()
à la place de
$1
ça marche.

Pourtant avec la commande date le système reconnaît cette date :
01-Jun-18 12:00:00 AM EDT
, et je peux passer au format 24h. Ce qui est mon objectif car windows 10 avec Excel ne reconnait pas ce format de date
01-Jun-18 12:00:00 AM EDT
.

Avez-vous une idée pour résoudre ce problème.

Merci

10 réponses

  1. Modérateur
    Bonjour,

    Je pense que tu confonds :
    • strftime
      (qui convertit un timestamp en une chaîne de caractère)
    • strptime
      (qui existe en
      python
      mais qui ne semble pas exister en
      awk
      ), qui fait l'opération contraire (ce qui signifie que ce que tu cherches à faire est bien plus simple à réaliser en
      python
      qu'en
      awk
      ).


    Dans le code que tu as reporté $1 n'est pas un timestamp conforme au format utilisé par
    systime()
    et attendu par
    strftime
    , ce qui explique pourquoi ce dernier ne retrouve pas ses billes.

    Il faut donc procéder en deux temps, comme expliqué dans ce lien : d'abord extraire les éléments de la date afin de construire un timestamp bien formé avec
    mktime
    , puis utiliser ce timestamp avec
    strftime
    .

    Bonne chance
    0
    1. Merci pour votre réponse.

      Il faut que je vous dise qu'en fait j'utilise gawk qui je pense gère strftime. Comme je suis qu'un dédutant, ça va me prendre un peu de temps pour faire mes test.

      Merci encore.
      0
      1. Modérateur
        Bonjour,

        Est-ce qu'une solution écrite python pourrait te convenir ? Parce qu'en
        awk
        ça se fait mais il faut passer par une expression rationnelle, extraire les bons bouts, faire un
        mktime
        puis un
        strftime
        ce qui est un peu rébarbatif...

        Bonne chance
        0
        1. J'aimerais bien voir le code Python que je connais peu.
          Comme je suis au Québec, il se peut qu'il y ai des délais entre les questions et réponses.
          Le véritable format de mes date c'est '01-Jun-19 12:00:00 AM EDT' ou EST.

          Merci.
          0
          1. Modérateur
            Bonjour

            Script minimal

            toto.py

            #!/usr/bin/env python3
            
            import datetime
            
            s_in = "01-Jun-18 11:22:33 PM EDT"
            format_in = "%d-%b-%y %I:%M:%S %p EDT"
            format_out = "%Y-%m-%d %H:%M:%S"
            s_out = datetime.datetime.strptime(s_in, format_in).strftime(format_out)
            print(s_out)


            Note que dans
            format_in
            , l'heure est chargée avec
            %I
            et
            %p
            (format AM/PM). Il est important d'utiliser
            %I
            et non
            %H
            considérerait que l'heure va de
            0
            à
            23
            . Pour
            format_out
            c'est le contraire, on veut une heure qui va de
            0
            à
            23
            et donc on utilise bien
            %H
            .

            Exécution :

            python3 toto.py


            Résultat :

            2018-06-01 23:22:33


            Script avec un fichier

            toto.py

            #!/usr/bin/env python3
            
            import datetime, sys
            
            def translate_date(s_in):
                format_in = "%d-%b-%y %I:%M:%S %p EDT"
                format_out = "%Y-%m-%d %H:%M:%S"
                return datetime.datetime.strptime(s_in, format_in).strftime(format_out)
            
            with open(sys.argv[1]) as f:
                for line in f.readlines():
                    try:
                        print(translate_date(line.strip()))
                    except Exception as e:
                        print(e, file=sys.stderr)


            toto.txt

            01-Jun-18 11:22:33 PM EDT
            02-Feb-19 11:33:55 AM EDT
            29-Deb-20 9:17:47 PM EDT


            Exécution

            python3 toto.py toto.txt


            Résultat

            2018-06-01 23:22:33
            2019-02-02 11:33:55
            2020-12-29 21:17:47


            Bonne chance
            0
            1. J'ai ça comme résultat avec
              gawk
              :

              gawk -F, '
              {
              split($1,a,/[-: ]/);
              ts = sprintf("%4d %02d %02d %2d %2d %2d", a[3], a[2], a[1], a[7] ~ /^[Pp]/ ? a[4]+12 : a[4], a[5], a[6]);
              MaDate = strftime("%Y-%m-%d %H:%M:%S", mktime(ts))
              }
              {print MaDate ,$2,$3}' TestDate.txt


              Mais il y a un problème avec
               ~ /^[Pp]/ ? a[4]+12
              parce que le résultat me donne 12 heure pour minuit et 00 pour midi. Je vais avoir besoin d'une exception.

              comme ceci :
              2018-06-01 11:30:00 20.8 54.8
              2018-06-01 11:45:00 20.9 55.5
              2018-06-02 00:00:00 21 56
              2018-06-02 00:15:00 21 55.8
              2018-06-02 00:30:00 20.9 55.5
              2018-06-02 00:45:00 20.9 55.5
              2018-06-01 13:00:00 20.8 55.4
              2018-06-01 13:15:00 20.8 55.3

              Donc j'ai ma date avec l'heure, la température et l'humidité.

              Je suis très comptant de voir votre script. Je vais l'étudier très attentivement.

              Un gros merci pour votre disponibilité. Si vous avez le temps de regarder ma commande gawk cela me ferais grand plaisir.
              0
              1. Modérateur
                Mais il y a un problème avec ~ /^[Pp]/ ? a[4]+12 parce que le résultat me donne 12 heures pour minuit et 00 pour midi. Je vais avoir besoin d'une exception.

                Oui donc dans l'idée tu regardes s'il est écrit quelque chose qui commence par P ou p (comme pm) pour décider si tu dois ajouter douze heures. Ce n'est pas parfaitement rigoureux mais c'est sans doute suffisant dans ton cas. Par contre il faut effectivement ne faire cet ajout que si a[4] ne vaut pas 0 ou 12. J'imagine qu'il faudrait donc raffiner ton test comme suit :

                    ~ /^[Pp][Mm]/ && a[4] != 0 && a[4] != 12 ? a[4]+12 : a[4]


                ... mais bon tu l'auras compris, pour moi ça donne un code sensiblement plus compliqué à lire que l'exemple python que je te t'ai donné. La méthode
                split
                est intéressante : elle est un peu moins rigoureuse qu'une expression rationnelle mais est plus facile à mettre en œuvre, donc pourquoi pas...

                Bonne chance
                0
            2. Pourquoi deux fois datetime.datetime. dans le code Python?
              0
              1. Modérateur
                Parce que c'est la classe datetime importée depuis le module datetime. Il se trouve que le nom du module et de la classe sont les mêmes.

                Note qu'il serait aussi possible d'écrire :

                from datetime import datetime
                
                def translate_date(s_in):
                    format_in = "%d-%b-%y %I:%M:%S %p EDT"
                    format_out = "%Y-%m-%d %H:%M:%S"
                    return datetime.strptime(s_in, format_in).strftime(format_out)


                Et donc ici
                strptime
                est une méthode statique de l'objet
                datetime
                (importé depuis le module
                datetime
                )
                0
            3. Savez-vous s'il y a une limite de taille de fichier (ex: 96000 lignes) avec gawk ?
              0
              1. Modérateur
                Non je ne sais pas. Teste et tu verras bien :-)
                0
            4. Dabord merci,

              Quel éditeur utilisez-vous avec Python ?

              De plus, je suis impressionné par votre disponibilté, c'est presqu'un cours privé.

              Pour ma part, j'ai terminé mon scrit
              gawk
              le voici.

              awk -F, '

              {gsub(/-Jan-/, "-01-"); gsub(/-Feb-/, "-02-"); gsub(/-Mar-/, "-03-"); gsub(/-Apr-/, "-04-"); gsub(/-May-/, "-05-"); gsub(/-Jun-/, "-06-"); gsub(/-Jul-/, "-07-"); gsub(/-Aug-/, "-08-"); gsub(/-Sep-/, "-09-"); gsub(/-Oct-/, "-10-"); gsub(/-Nov-/, "-11-"); gsub(/-Dec-/, "-12-")}
              {
              split($1,a,/[-: ]/);
              ts = sprintf("%4d %02d %02d %2d %2d %2d", a[3]~ /[0-9][0-9]/ ? a[3]+2000: a[3], a[2], a[1], a[7] ~ /^[Pp]/ ? a[4]+12 : a[4], a[5], a[6]);
              MaDate = strftime("%Y-%m-%d %H:%M:%S", mktime(ts))
              }
              {print MaDate ,$2,$3}' HighWall2020.csv | gawk ' { gsub(/\s12:/, " 25:"); gsub(/\s00/, " 12") ;gsub(/\s25:/, " 00:") } { print $1,$2"\t"$3"\t"$4}' | tee Nom.txt
              0
              1. Modérateur
                Quel éditeur utilisez-vous avec Python ?

                Celui que tu veux, un script python n'est qu'un fichier texte (comme n'importe quel fichier texte), dont l'extension est par convention
                .py
                .

                De plus, je suis impressionné par votre disponibilté, c'est presqu'un cours privé.

                Ho, c'est juste que là je dépile mes messages et que tu tombes à la bonne heure, mais oui j'essaye de regarder régulièrement ce qui se passe sur le forum.

                Pour ma part, j'ai terminé mon scrit gawk le voici.

                Merci de l'avoir partagé :-)
                0
            5. Jusqu'à présent je suis arrivé à traiter un fichier de 32000 lignes.

              J'ai essayé différents éditeurs, et le plus complet pour moi est bpython, qui tourne dans un terminal (vérification de syntaxe, autocomplétion).
              0
              1. Modérateur
                Attention il ne faut pas confondre interpréteur et éditeur.
                • Un interpréteur permet de taper et d'exécuter des commandes python. Lesdites commandes ne sont pas écrites dans un fichier, elles sont juste en mémoire. Parmi eux, on peut citer les plus classiques :
                  • python3
                    (resp.
                    python
                    pour Python2) est l'interpréteur standard en mode texte, utilisé pour exécuter un programme ;
                  • ipython3
                    (resp.
                    ipython
                    pour Python2) qui est proche de
                    bpython
                    plus évolué ;
                  • .
                    jupyter-notebook
                    et son successeur
                    jupyterlab
                    sont deux interpréteurs, tout deux construits au dessus de
                    ipython3
                    qui s'utilisent dans un navigateur web après avoir lancé le serveur correspondant.
                • Un éditeur permet de créer et modifier un ou des fichiers textes (en particulier Python). Sous linux la plupart des éditeurs sont bien plus évolués que le bloc note de windows et fournissent des fonctionnalités proches de notepad++ : coloration syntaxique, indentation intelligente, etc.
                  • les éditeurs génériques en mode texte sont
                    nano
                    ,
                    vim
                    ,
                    emacs
                    . Ces deux derniers sont suffisamment évolué pour offrir une auto-complétion sémantique ;
                  • les éditeurs génériques graphiques sont
                    gedit
                    ,
                    kwrite
                    ;
                  • .l'environnement graphique de développement (IDE) traditionnellement utilisé en python est
                    pycharm
                    mais ne prend son intérêt que pour un projet python impliquant plusieurs fichiers (sinon un éditeur moins évolué fait amplement l'affaire).


                Bonne chance
                0