Конвертировать дату и время на лету в BASH

Я запустил dpkg -l> pl.txt. Затем сравнил перечисленные пакеты с установленными в Synaptic Package Manager. Между ними было полное соответствие один-к-одному. Теперь я периодически сохраняю файл pl.txt на моем Google Диске. Если мне каждый раз придется переустанавливать систему, я буду использовать список сохраненных текстовых файлов, чтобы переустановить те пакеты, которые я использовал.

0
01.05.2018, 23:14
3 ответа

Требуется GNU awk для встроенных функций времени

gawk -F, -v OFS=, '
    BEGIN {
        # assumes english month names
        split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", m, ",")
        for (idx in m) months[m[idx]] = idx
        delete m
    }
    function date2timestamp(datestamp,    tmp,now,timestamp,year,hour,minute) {
        now = systime()
        split(datestamp, tmp, " ")
        if (tmp[3] ~ /:/) {
            year = strftime("%Y", now)
            hour = substr(tmp[3], 1, 2)
            minute = substr(tmp[3], 4, 2)
        }
        else {
            year = tmp[3]
            hour = minute = 0
        }
        timestamp = mktime(year " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        if (timestamp > now)
            timestamp = mktime((year-1) " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        return strftime("%Y%m%d%H%M00", timestamp)
    }
    {
        $1 = date2timestamp($1)
        print
    }
' file

выход

20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

Ваш входной файл выглядит как результат разбораls -l. Вы можете пропустить этот файл и сделать что-то вроде

stat -c '%Y,%n' * | gawk -F, -v OFS=, '{$1 = strftime("%Y%m%d%H%M%S", $1)}1'

Это небезопасно (в смысле обработки имен файлов с переводом строки ), но это даст вам точное mtime файла.

0
28.01.2020, 02:32

Не знаю, как ваши ожидаемые результаты соотносятся с вашими входными данными. Я бы предложил:

$ perl -MPOSIX -MDate::Parse -pe 's{[^,]*}{
   strftime("%Y%m%d%H%M%S", localtime str2time($&))}e' <your-file
20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

Чтобы использовать способность GNU dateанализировать эти даты и избежать выполнения одного dateвызова в строке, вы можете (использовать оболочку с поддержкой процесса в стиле ksh --замены (как ksh, bash или zsh)):

paste -d, <(<yourfile cut -d, -f1 | date -f- +%Y%m%d%H%M%S) \
           <(<yourfile cut -d, -f2-)

Обратите внимание, однако, что это дает:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

Хотя это то, о чем вы спрашивали, маловероятно, что это то, что вам нужно, поскольку эти Nov 29 15:15кажутся скорее отметками времени из 2017 (прошлого года ), чем из будущего.

Похоже, что эти даты соответствуют ls -lв локали POSIX. Таким образом, вы можете адаптировать эту функцию из другого Q&A , чтобы преобразовать ее в более полезный формат. Или лучше использовать лучший способ, чем ls -l, для хранения дат файлов в файле в первую очередь (, например GNU find -printf, или GNU date -r, или zsh stat, или GNU/BSD stat, или ast ls --format... ), где вы можете использовать более полезный, точный и недвусмысленный формат.

2
28.01.2020, 02:32

Если ноль 000000подходит как HHMMSSдля записей без данных о времени , используйте следующийawkподход:

awk 'BEGIN{ FS = OFS = "," }
     { 
         cmd = "date -d\042" $1 "\042 +%Y%m%d%H%M%S";
         cmd | getline d; close(cmd);
         print d, $2
     }' file

Выход:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
0
28.01.2020, 02:32

Теги

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