Cómo convertir marcas de tiempo a fechas en Bash?
Necesito un comando o script de shell que convierta una marca de tiempo Unix en una fecha. La entrada puede venir desde el primer parámetro o desde stdin, permitiendo los siguientes patrones de uso:
ts2date 1267619929
Y
echo 1267619929 | ts2date
Ambos comandos deben salir "Mié Mar 3 13:38:49 2010".
12 answers
En versiones posteriores de distribuciones comunes de Linux puede usar:
date -d @1267619929
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-03 12:47:51
date -r <number>
Funciona para mí en Mac OS X.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-22 12:52:23
Esta versión es similar a respuesta de chiborg, pero elimina la necesidad de la externa tty
y cat
. Usa date
, pero podría usar gawk
con la misma facilidad. Puede cambiar el shebang y reemplazar los corchetes dobles por corchetes simples y esto también se ejecutará en 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 17:13:39
Puede usar GNU date, por ejemplo,
$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"
O
$ date -ud @1267619929
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 09:40:12
Puedes usar este sencillo script awk:
#!/bin/gawk -f
{ print strftime("%c", $0); }
Uso de la muestra:
$ echo '1098181096' | ./a.awk
Tue 19 Oct 2004 03:18:16 AM PDT
$
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-03 12:45:09
Uso esto al convertir archivos de registro o monitorearlos:
tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-17 07:58:03
He escrito un guion que hace esto yo mismo:
#!/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); }'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-03 13:41:54
En esta respuesta copio la respuesta de Dennis Williamson y la modifico ligeramente para permitir un gran aumento de velocidad al canalizar una columna de muchas marcas de tiempo al script. Por ejemplo, la canalización de 1000 marcas de tiempo al script original con xargs-n1 en mi máquina tomó 6.929 s en lugar de 0.027 s con esta versión modificada:
#!/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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-25 23:08:14
En OSX, o BSD, hay una bandera -r
equivalente que aparentemente toma una marca de tiempo unix. Aquí hay un ejemplo que ejecuta date cuatro veces: una para la primera fecha, para mostrar lo que es; una para la conversión a marca de tiempo unix con %s
, y finalmente, una que, con -r
, convierte lo que %s
proporciona de nuevo a una cadena.
$ date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017
Al menos, parece funcionar en mi máquina.
$ 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-24 21:46:46
Desde Bash 4.2 puedes usar el formato printf
's %(datefmt)T
:
$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET
Eso es bueno, porque es una concha incorporada. El formato para datefmt es una cadena aceptada por strftime(3)
(véase man 3 strftime
). Aquí %c
es:
%c
La representación de fecha y hora preferida para el actual local.
Ahora, si desea un script que acepte un argumento y, si no se proporciona ninguno, lea stdin, puede proceder como:
#!/bin/bash
if (($#)); then
printf '%(%c)T\n' "$@"
else
while read -r line; do
printf '%(%c)T\n' "$line"
done
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 17:27:57
Algún ejemplo:
$ date Tue Mar 22 16:47:06 CST 2016 $ date -d "Tue Mar 22 16:47:06 CST 2016" "+%s" 1458636426 $ date +%s 1458636453 $ date -d @1458636426 Tue Mar 22 16:47:06 CST 2016 $ date --date='@1458636426' Tue Mar 22 16:47:06 CST 2016
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-22 08:58:33
En PHP
$unix_time = 1256571985;
echo date("Y-m-d H:i:s",$unix_time)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-03 12:43:35