J'ai besoin d'une commande ou d'un script Shell qui convertit un horodatage Unix en date. L'entrée peut provenir du premier paramètre ou de stdin, permettant les modèles d'utilisation suivants:
ts2date 1267619929
et
echo 1267619929 | ts2date
Les deux commandes doivent générer "Wed Mar 3 13:38:49 2010".
Sur les versions ultérieures des distributions Linux courantes, vous pouvez utiliser:
date -d @1267619929
date -r <number>
fonctionne pour moi sur Mac OS X.
Cette version est similaire à chiborg's answer, mais elle élimine le besoin d'utiliser les variables externes tty
et cat
. Il utilise date
, mais pourrait tout aussi bien utiliser gawk
. Vous pouvez changer le Shebang et remplacer les doubles crochets par des simples et cela fonctionnera également dans sh
.
#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
if [[ -p /dev/stdin ]] # input from a pipe
then
read -r p
else
echo "No timestamp given." >&2
exit
fi
else
p=$1
fi
date -d "@$p" +%c
Vous pouvez utiliser la date GNU, par exemple,
$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"
ou
$ date -ud @1267619929
Vous pouvez utiliser ce simple script awk:
#!/bin/gawk -f
{ print strftime("%c", $0); }
Exemple d'utilisation:
$ echo '1098181096' | ./a.awk
Tue 19 Oct 2004 03:18:16 AM PDT
$
J'utilise ceci lors de la conversion des fichiers journaux ou de leur surveillance:
tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'
Dans cette réponse, je recopie la réponse de Dennis Williamson et la modifie légèrement pour permettre une augmentation considérable de la vitesse lors du transfert d’une colonne contenant de nombreux horodatages au script. Par exemple, acheminer 1000 horodatages vers le script d'origine avec xargs -n1 sur ma machine a nécessité 6,929 secondes au lieu de 0,027 secondes avec cette version modifiée:
#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
if [[ -p /dev/stdin ]] # input from a pipe
then
cat - | gawk '{ print strftime("%c", $1); }'
else
echo "No timestamp given." >&2
exit
fi
else
date -d @$1 +%c
fi
J'ai écrit un script qui le fait moi-même:
#!/bin/bash
LANG=C
if [ -z "$1" ]; then
if [ "$(tty)" = "not a tty" ]; then
p=`cat`;
else
echo "No timestamp given."
exit
fi
else
p=$1
fi
echo $p | gawk '{ print strftime("%c", $0); }'
Dans OSX ou BSD, il existe un indicateur équivalent -r
qui prend apparemment un horodatage Unix. Voici un exemple qui exécute la date quatre fois: une fois pour la première date, pour montrer ce que c'est; un pour la conversion en horodatage Unix avec %s
, et enfin un autre qui, avec -r
, convertit ce que %s
fournit en chaîne.
$ date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017
Au moins, semble fonctionner sur ma machine.
$ uname -a
Darwin XXX-XXXXXXXX 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
Depuis Bash 4.2, vous pouvez utiliser le format printf
's %(datefmt)T
:
$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET
C'est bien, parce que c'est un shell intégré. Le format de datefmt est une chaîne acceptée par strftime(3)
(voir man 3 strftime
). Ici %c
est:
%c
Représentation préférée de la date et de l'heure pour le fichier .__ actuel. lieu.
Maintenant, si vous voulez un script qui accepte un argument et qui, si aucun n'est fourni, lit stdin, vous pouvez procéder comme suit:
#!/bin/bash
if (($#)); then
printf '%(%c)T\n' "$@"
else
while read -r line; do
printf '%(%c)T\n' "$line"
done
fi
Vous pouvez obtenir une date formatée à partir de l'horodatage comme ceci
date +'%Y-%m-%d %H:%M:%S' -d "@timestamp"
quelques exemples:
$ date mar 22 mars 16:47:06 CST 2016 $ date - d "mar 22 mars 16:47:06 CST 2016" "+% s" 1458636426 $ date +% s 1458636453 $ date -d @ 1458636426 Mar 22 Mar 16:47:06 CST 2016 $ date - date ='@1458636426' Tue 22 mars 16:47:06 CST 2016