Преобразование временной метки Unix в удобочитаемое время

Думаю, вы сможете использовать pandoc . Он читает со стандартного ввода и может выводить в различных форматах

.

16
23.10.2019, 21:33
6 ответов

Если строка начинается с временной метки unix, то так и должно быть:

perl -pe 's/^(\d+)/localtime $1/e' inputfilename

perl -pвызывает цикл над выражением, переданным с помощью -e, который выполняется для каждой строки ввода и печатает буфер в конце цикла.

Выражение использует команду подстановки s///для сопоставления и захвата последовательности цифр в начале каждой строки и замены ее представлением местного времени этих цифр, интерпретируемым как отметка времени unix. /eуказывает, что шаблон замены должен оцениваться как выражение.

21
27.01.2020, 19:47

Если ваш AWK Gawk , вы можете использоватьstrftime:

gawk '{ print strftime("%c", $1) }'

преобразует метку времени в первом столбце в представление даты/времени по умолчанию для текущей локали.

Вы можете использовать это для преобразования контента перед его просмотром:

gawk '{ print gensub($1, strftime("%c", $1), 1) }' inputfile
20
27.01.2020, 19:47

использовать "дата"

Для этого вам не нужен perl, awk, php или длинное арифметическое выражение. Вы можете сделать это с помощью gnu "date", что действительно очень полезно для такого рода вещей. Для других версий «свидания» ваш YMMV.

$ date -d '1/1/1970 GMT 1571889039 seconds'
Wed Oct 23 20:50:39 PDT 2019

Здесь происходит то, что вы указываете время и корректируете его. Время — полночь 1 января 1970 года по Гринвичу, эпоха Unix. (Полночь не указана явно; он используется неявно каждый раз, когда вы опускаете время суток.)

Корректировка, 1571889039 секунд, добавляется ко времени. Вместо этого используйте свою временную метку, очевидно. В документах для этой функции используется слово «относительный».

Существует более краткая версия, документированная только примером на странице руководства, которая работает для более новых версий gnu date:

$ date -d @2147483647
Mon Jan 18 19:14:07 PST 2038

Если вам нужно часто манипулировать датами, изучите свою команду date. Это больше, чем просто часы; это библиотека даты/времени для оболочки.

7
27.01.2020, 19:47

Как уже было сказано, на самом деле нет портативного способа сделать это с помощью оболочки или даже АВК. GAWK может это сделать, но GAWK strftimeнедоступен для некоторых версии AWK, а именно MAWK. И MAWK используется с некоторыми популярными дистрибутивами, для например Дебиан.

Я согласен, что для этого должна быть доступна портативная оболочка или решение AWK. Но так как это не так и, вероятно, не будет в течение многих лет, если вообще когда-либо, лучшее решение - просто используйте язык программирования. Был предложен Perl, другой вариант — PHP :

.
$ cat input.txt
1571806800 blue
1571720400 green
1571634000 orange
1571547600 red
1571461200 yellow

$ cat app.php
<?php
$r1 = fopen('input.txt', 'r');
while (true) {
   $s1 = fgets($r1);
   if ($s1 === false) {
      break;
   }
   $a1 = explode(' ', $s1);
   $n1 = + $a1[0];
   echo date(DATE_W3C, $n1), "\n";
}

$ php app.php
2019-10-23T05:00:00+00:00
2019-10-22T05:00:00+00:00
2019-10-21T05:00:00+00:00
2019-10-20T05:00:00+00:00
2019-10-19T05:00:00+00:00
1
27.01.2020, 19:47

Как Дэн упоминает в своем ответе , команду Gnu date(1)можно задан параметр -dс датой или отметкой времени, который он будет рассматривать как дата, которую необходимо вывести. (Это недоступно в POSIX или BSD. date(1)команды, однако.)@1571806800— это формат, используемый для укажите целое число time_t.

Вот функция оболочки Bash, которая действует как фильтр, читая строки из ввод, предполагая, что любое слово, начинающееся со строки, состоящей только из цифр, является отметку времени и преобразовать ее в удобочитаемый -вывод в одном из моих любимые форматы.

ts2hr() {
    while read n rest; do
        if [[ $n =~ ^[0-9][0-9]*$ ]]; then
            echo "$(date -d @"$n" +"%Y-%m-%d %T")" "$rest"
        else
            echo "$n" "$rest"
        fi
    done
}

Вот как выглядят некоторые входные и выходные данные:

ts2hr <<____
1571806123 first line
# A comment?
1571720456 second date's here
Just a regular sentence.
1571547789 The last line.
____
2019-10-23 13:48:43 first line
# A comment?
2019-10-22 14:00:56 second date's here
Just a regular sentence.
2019-10-20 14:03:09 The last line.

Вы можете настроить функцию по мере необходимости для обработки конкретного ввода. и форматы вывода, которые вам нужны, а также инструменты, которые у вас есть доступный. Вышеупомянутая функция является Bash главным образом потому, что оператор =~упростили сопоставление с образцом; если вам это нужно в оболочке Bourne, вы придется закодировать чек по-другому, если он вам вообще нужен.

10
27.01.2020, 19:47

Если у вас нет даты gnu или доступа к языку программирования с помощью strftime или его эквивалента, вам придется выполнять математические расчеты самостоятельно, что выходит за рамки кодового гольфа.

unix_to_iso_utc () {
    local day_unix=$(($1 / 86400))
    local day_offset=$(($1 % 86400))
    local d=$(($day_unix + 719468))
    local y=$((($d - ($d+2+3*$d/146097)/1461 + ($d-$d/146097)/36524 - ($d+1)/146097)/365))
    local y_d=$((365*$y + $y/4 - $y/100 + $y/400))
    local y_offset=$(($d - $y_d))
    local m=$((($y_offset - ($y_offset+20)/50) / 30))
    local m_d=$((30*$m + 3*($m+4)/5 - 2))
    local day=$(($y_offset - $m_d + 1))
    local m_cont=$((12*$y + $m + 2))
    local year=$(($m_cont/12))
    local month=$(($m_cont%12 + 1))
    local hour=$(($day_offset / 3600))
    local hour_offset=$(($day_offset % 3600))
    local minute=$(($hour_offset / 60))
    local second=$(($hour_offset % 60))
    DATE=$(printf "%04d-%02d-%02dT%02d:%02d:%02d" $year $month $day $hour $minute $second)
}

Вероятно, на тот момент у вас также не было базы данных часовых поясов, что может стать серьезной практической проблемой, если только вы не сможете жестко запрограммировать то, что вам нужно.

2
27.01.2020, 19:47

Теги

Похожие вопросы