Problème de formatage de date avec awk strftime

dplourde512 -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
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

$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. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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
  2. dplourde512
     
    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
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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
  4. dplourde512
     
    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
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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
  7. dplourde512
     
    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. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      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
  8. dplourde512
     
    Pourquoi deux fois datetime.datetime. dans le code Python?
    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      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
  9. dplourde512
     
    Savez-vous s'il y a une limite de taille de fichier (ex: 96000 lignes) avec gawk ?
    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      Non je ne sais pas. Teste et tu verras bien :-)
      0
  10. dplourde512
     
    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. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      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
  11. dplourde512
     
    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. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      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