web-dev-qa-db-fra.com

Comment convertir des horodatages en dates dans Bash?

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".

212
chiborg

Sur les versions ultérieures des distributions Linux courantes, vous pouvez utiliser:

date -d @1267619929
436
a'r
date -r <number>

fonctionne pour moi sur Mac OS X.

136
rafaelzlisboa

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
25

Vous pouvez utiliser la date GNU, par exemple,

$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"

ou 

$ date -ud @1267619929
15
ghostdog74

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
$
10
codaddict

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 }'
4
user3544224

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
3
webb

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); }'
3
chiborg

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
2
Dan Farrell

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
2
gniourf_gniourf

Vous pouvez obtenir une date formatée à partir de l'horodatage comme ceci

date +'%Y-%m-%d %H:%M:%S' -d "@timestamp"
1
andranikasl

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 


1
kai