Как конвертировать временные метки в даты в 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 С, а не 0.027 с этой модифицированной версией:
#!/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 timestamp с%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
). Здесь%c
- это:
%c
предпочтительное представление даты и времени для текущего место действия.
теперь, если вы хотите скрипт, который принимает аргумент и, если он не указан, читает stdin, вы можете действовать следующим образом:
#!/bin/bash if (($#)); then printf '%(%c)T\n' "$@" else while read -r line; do printf '%(%c)T\n' "$line" done fi