Problème de formatage de date avec awk strftime

Signaler
-
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
-
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

Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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

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.
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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
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.
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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
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.
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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
Pourquoi deux fois datetime.datetime. dans le code Python?
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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
)

Savez-vous s'il y a une limite de taille de fichier (ex: 96000 lignes) avec gawk ?
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
Non je ne sais pas. Teste et tu verras bien :-)
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
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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é :-)
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).
Messages postés
29745
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
21 avril 2021
7 072
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