it-swarm.com.de

Wie konvertiert man Zeitstempel in Datumsangaben in Bash?

Ich benötige einen Shell-Befehl oder ein Skript, das einen Unix-Zeitstempel in ein Datum konvertiert. Die Eingabe kann entweder vom ersten Parameter oder von stdin stammen, wobei die folgenden Verwendungsmuster berücksichtigt werden:

ts2date 1267619929

und

echo 1267619929 | ts2date

Beide Befehle sollten "Mi Mar 3 13:38:49 2010" ausgeben.

212
chiborg

In späteren Versionen gängiger Linux-Distributionen können Sie Folgendes verwenden:

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

arbeitet für mich unter Mac OS X.

136
rafaelzlisboa

Diese Version ähnelt der Antwort von chiborg, macht jedoch die externe Variable tty und cat überflüssig. Es verwendet date, könnte jedoch genauso einfach gawk verwenden. Sie können den Shebang ändern und die doppelten eckigen Klammern durch einzelne ersetzen. Dies wird auch in sh ausgeführt.

#!/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

Sie können beispielsweise das Datum GNU verwenden.

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

oder 

$ date -ud @1267619929
15
ghostdog74

Sie können dieses einfache awk-Skript verwenden:

#!/bin/gawk -f   
{ print strftime("%c", $0); }

Verwendungsbeispiel:

$ echo '1098181096' | ./a.awk 
Tue 19 Oct 2004 03:18:16 AM PDT
$
10
codaddict

Ich verwende dies zum Konvertieren von Protokolldateien oder zum Überwachen dieser:

tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'
4
user3544224

In dieser Antwort kopiere ich die Antwort von Dennis Williamson und modifiziere sie leicht, um eine enorme Geschwindigkeitserhöhung zu ermöglichen, wenn eine Spalte mit vielen Zeitstempeln an das Skript übergeben wird. Das Übergeben von 1000 Zeitstempeln an das Originalskript mit xargs -n1 auf meinem Computer kostete beispielsweise 6,929 Sekunden gegenüber 0,027 Sekunden bei dieser modifizierten Version:

#!/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

Ich habe ein Skript geschrieben, das dies selbst tut:

#!/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

In OSX oder BSD gibt es ein entsprechendes -r-Flag, das anscheinend einen Unix-Zeitstempel benötigt. Hier ein Beispiel, das viermal ausgeführt wird: einmal für das erste Datum, um zu zeigen, was es ist; eine für die Konvertierung in Unix-Zeitstempel mit %s und schließlich eine, die mit -r das konvertiert, was %s in eine Zeichenfolge zurückgibt.

$  date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017

Zumindest scheint auf meiner Maschine zu funktionieren.

$ 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

Seit Bash 4.2 können Sie das %(datefmt)T-Format von printf verwenden:

$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET

Das ist schön, weil es eine Shell ist. Das Format für datefmt ist eine von strftime(3) akzeptierte Zeichenfolge (siehe man 3 strftime). Hier ist %c:

%c Die bevorzugte Datums- und Uhrzeitdarstellung für das aktuelle Gebietsschema.


Wenn Sie nun ein Skript wünschen, das ein Argument akzeptiert, und wenn keines angegeben ist, stdin liest, können Sie wie folgt vorgehen:

#!/bin/bash

if (($#)); then
    printf '%(%c)T\n' "[email protected]"
else
    while read -r line; do
        printf '%(%c)T\n' "$line"
    done
fi
2
gniourf_gniourf

Sie können das formatierte Datum wie folgt aus dem Zeitstempel abrufen

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

ein Beispiel:

 $ date 
 Di Mar 22 16:47:06 CST 2016 

 $ date -d "Di Mar 22 16:47:06 CST 2016" "+% s" 
 1458636426

 $ date +% s 
 1458636453 

 $ date -d @ 1458636426 
 Di Mar 22 16:47:06 CST 2016 

 $ date - date ='@1458636426'
Tue Mar 22 16:47:06 CST 2016 


1
kai