programas - scripts bash ejemplos
¿Cómo convertir las marcas de tiempo a las fechas en Bash? (12)
Desde Bash 4.2 puede usar el formato %(datefmt)T
printf
'' %(datefmt)T
:
$ printf ''%(%c)T/n'' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET
Eso es bueno, porque es un shell incorporado. El formato para datefmt es una cadena aceptada por strftime(3)
(ver man 3 strftime
). Aquí %c
es:
%c
La representación de fecha y hora preferida para la configuración regional actual.
Ahora, si desea un script que acepte un argumento y, si no se proporciona ninguno, lea la entrada estándar, puede proceder como:
#!/bin/bash
if (($#)); then
printf ''%(%c)T/n'' "$@"
else
while read -r line; do
printf ''%(%c)T/n'' "$line"
done
fi
Necesito un comando o script de shell que convierta una marca de tiempo Unix en una fecha. La entrada puede provenir del primer parámetro o de la entrada estándar, lo que permite los siguientes patrones de uso:
ts2date 1267619929
y
echo 1267619929 | ts2date
Ambos comandos deben mostrar "Mié 3 de marzo 13:38:49 2010".
En OSX, o BSD, hay una marca -r
equivalente que aparentemente toma una marca de tiempo de Unix. Aquí hay un ejemplo que se ejecuta la fecha cuatro veces: una vez para la primera fecha, para mostrar lo que es; uno para la conversión a la marca de tiempo de Unix con %s
, y finalmente, uno que, con -r
, convierte lo que %s
proporciona de nuevo en 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
En PHP
$unix_time = 1256571985;
echo date("Y-m-d H:i:s",$unix_time)
En esta respuesta, copio la respuesta de Dennis Williamson y la modifico ligeramente para permitir un gran aumento de velocidad al colocar una columna con muchas marcas de tiempo en el script. Por ejemplo, agregar 1000 marcas de tiempo al script original con xargs -n1 en mi máquina tomó 6.929s en lugar de 0.027s 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
En versiones posteriores de distribuciones de Linux comunes puede usar:
date -d @1267619929
Esta versión es similar a la respuesta de chiborg , pero elimina la necesidad del tty
externo y del cat
. Utiliza la date
, pero podría usar gawk
misma facilidad. Puede cambiar el shebang y reemplazar los corchetes dobles con uno solo 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
He escrito un guión 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); }''
Puedes usar este simple 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
$
Puedes usar la fecha de GNU, por ejemplo,
$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"
o
$ date -ud @1267619929
Uso esto cuando convierto archivos de registro o los controlo:
tail -f <log file> | gawk /
''{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }''
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
date -r <number>
funciona para mí en Mac OS X.