Converter hora de data no fly em BASH

0

Eu tenho um arquivo com os seguintes enteries

Nov 29 15:15 ,alert_logevent
Nov 29 15:15 ,alert_webhook
Nov 29 15:15 ,appsbrowser
Oct 20 2017 ,ClearPassOnSplunk_2
Oct 10 2017 ,Dnslookup
Oct 12 2017 ,domainCategories

Eu quero converter o date time para AAAAMMDDHHMMSS sem usar loops alguma coisa assim

 cat SOMEFILE_WITH_DATE_AND_DATE | awk '{print "date -d \""$1, $2, $3"\"" " +" "%Y%m%d%H%M%S" , $4 }'

Eu quero que a saída fique assim

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20181129151500,appsbrowser

e assim por diante

Eu tentei a função system () no awk, mas ela não aceita mais de 1 argumento.

    
por Shani 01.05.2018 / 22:09

3 respostas

2

Não tenho certeza de como sua saída esperada se relaciona com sua entrada. Eu sugeriria:

$ 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

Para usar a capacidade do GNU date de analisar essas datas e evitar executar uma invocação de date por linha, você poderia fazer (assumindo um shell com suporte a substituição de processo no estilo ksh (como ksh, bash ou zsh)):

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

Observe, no entanto, que isso é:

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

Embora seja o que você pediu, parece improvável que seja o que você quer, pois os Nov 29 15:15 têm mais probabilidade de serem timestamps de 2017 (ano passado) do que alguns no futuro.

Aqui, parece que essas datas são reportadas por ls -l na localidade POSIX. Então portável, você poderia adaptar essa função de outra Q & A para convertê-la em um formato mais útil. Ou melhor, use uma maneira melhor do que ls -l para armazenar datas do arquivo no arquivo (como GNU find -printf ou GNU date -r ou zsh stat , ou GNU / BSD stat ou ast ls --format ...) onde você pode usar um formato mais útil, preciso e não ambíguo.

    
por 01.05.2018 / 22:24
0

Se zero 000000 estiver ok como HHMMSS para entradas sem dados time , use a seguinte abordagem awk :

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

A saída:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
    
por 01.05.2018 / 22:25
0

Requer o GNU awk para as funções de tempo embutido

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

saída

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

Seu arquivo de entrada parece o resultado de análise ls -l . Você pode querer pular esse arquivo e fazer algo como

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

Isso não é seguro (no sentido de manipular nomes de arquivos com novas linhas), mas fornecerá o mtime preciso do arquivo.

    
por 01.05.2018 / 22:39