Как конвертировать метки времени в даты в Bash?
мне нужна команда или скрипт, который преобразует метку времени Unix для даты. Входной сигнал может прийти или от первого параметра или от stdin, позволяющ для следующих картин использования:
ts2date 1267619929
и
echo 1267619929 | ts2date
обе команды должны выводить "Wed Mar 3 13:38: 49 2010".
12 ответов
эта версия похожа на chiborg это ответ, но это устраняет необходимость для внешнего tty
и cat
. Он использует date
, но может так же легко использовать gawk
. Вы можете изменить shebang и заменить двойные квадратные скобки на одиночные, и это также будет работать в sh
.
#!/bin/bash
LANG=C
if [[ -z "" ]]
then
if [[ -p /dev/stdin ]] # input from a pipe
then
read -r p
else
echo "No timestamp given." >&2
exit
fi
else
p=
fi
date -d "@$p" +%c
вы можете использовать GNU date, например,
$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"
или
$ date -ud @1267619929
Вы можете использовать этот простой скрипт на awk:
#!/bin/gawk -f
{ print strftime("%c", ); }
пример использования:
$ echo '1098181096' | ./a.awk
Tue 19 Oct 2004 03:18:16 AM PDT
$
Я использую это при конвертации файлов журнала или их мониторинге:
tail -f <log file> | gawk \
'{ printf strftime("%c", ); for (i=2; i<NF; i++) printf $i " "; print $NF }'
Я написал скрипт, который делает это сам:
#!/bin/bash
LANG=C
if [ -z "" ]; then
if [ "$(tty)" = "not a tty" ]; then
p=`cat`;
else
echo "No timestamp given."
exit
fi
else
p=
fi
echo $p | gawk '{ print strftime("%c", ); }'
в этом ответе я копирую ответ Денниса Уильямсона и немного изменяю его, чтобы обеспечить значительное увеличение скорости при передаче столбца со многими метками времени в сценарий. Например, передача 1000 временных меток в исходный скрипт с xargs-n1 на моей машине заняла 6.929 s, а не 0.027 s с этой измененной версией:
#!/bin/bash
LANG=C
if [[ -z "" ]]
then
if [[ -p /dev/stdin ]] # input from a pipe
then
cat - | gawk '{ print strftime("%c", ); }'
else
echo "No timestamp given." >&2
exit
fi
else
date -d @ +%c
fi
в OSX или BSD есть эквивалент -r
флаг, который, по-видимому, принимает временную метку unix. Вот пример, который запускает дату четыре раза: один раз для первой даты, чтобы показать, что это такое; один для преобразования в метку времени unix с %s
, и, наконец, тот, который, с -r
, преобразует то, что %s
возвращает строку.
$ date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017
по крайней мере, кажется, работает на моей машине.
$ 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
С Bash 4.2 вы можете использовать printf
' s :
$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET
это хорошо, потому что это встроено в оболочку. Формат datefmt - строка, принятая strftime(3)
(см. man 3 strftime
). Вот!--6--> - это:
%c
предпочитаемое представление даты и времени для текущего место действия.
теперь, если вы хотите сценарий, который принимает аргумент и, если ни один не предоставляется, читает stdin, вы можете действовать как:
#!/bin/bash
if (($#)); then
printf '%(%c)T\n' "$@"
else
while read -r line; do
printf '%(%c)T\n' "$line"
done
fi
пример:
$ 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