Convertendo data e hora de 12 horas para 24 usando awk

4

Estou trabalhando com um arquivo csv que contém dados na seguinte estrutura:

"12345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333,"15/12/2017 4:26:00 PM"

Eu quero converter o horário de 12 horas em 24 horas. A seguir, mostramos o que estou tentando alcançar no final:

"12345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333,"15/12/2017 16:26:00"

Eu encontrei a seguinte resposta para uma pergunta que parece resolver a conversão do segmento de tempo do meu problema. link

Assim, com o acima, acredito que devo fazer o seguinte processo (provavelmente há um método mais eficiente):

  1. Separe temporariamente a data e a hora nos próprios registros

    "12345", "BLAH", "DEDA", "0,000", "1,131", "2,22222", "3,33333333", 15/12/2017 "," 4:26:00 PM "

  2. Segmente o registro de horário e converta-o no formato de 24 horas desejado
  3. Concatene os registros de data e hora em um único registro

Estou tentando conseguir isso usando awk e estou preso na primeira seção! É o awk para a ferramenta certa para este trabalho, ou você recomendaria uma ferramenta diferente?

Estou começando na etapa 1. Nem consigo segmentar com sucesso a data!

awk 'BEGIN {FS=","} { gsub(/[0-9]\{2\}\/[0-9]\{2\}\/[0-9]\{4\}/, "TESTING"); print }' myfile.csv
    
por GustavMahler 27.02.2018 / 17:47

2 respostas

5

Eu usaria perl aqui:

perl -pe 's{\b(\d{1,2})(:\d\d:\d\d) ([AP])M\b}{
  $1 + 12 * (($3 eq "P") - ($1 == 12)) . $2}ge'

Isso é adicionar 12 à parte da hora se PM (exceto 12PM) e mudar 12AM para 0.

Com awk , não fazendo a parte com limite de palavras (portanto, poderia dar falsos positivos em 123:21:99 AMERICA , por exemplo) e assumindo que há apenas uma ocorrência por linha:

awk '
  match($0, /[0-9]{1,2}:[0-9]{2}:[0-9]{2} [AP]M/) {
    split(substr($0, RSTART, RLENGTH), parts, /[: ]/)
    if (parts[4] == "PM" && parts[1] != 12) parts[1] += 12
    if (parts[4] == "AM" && parts[1] == 12) parts[1] = 0

    $0 = substr($0, 1, RSTART - 1) \
         parts[1] ":" parts[2] ":" parts[3] \
         substr($0, RSTART + RLENGTH)
  }
  {print}'
    
por 27.02.2018 / 18:17
0

Esta solução converte todos os itens do formato de 12 horas para o formato de 24 horas em cada linha.

gawk -F, '
{
    for(i = 1; i <= NF; i++) {
        if($i ~ /:[0-9]{2} [PA]M/) {
            split($i, arr, ":| ")

            if(arr[5] ~ /P/)
                arr[2] += 12 

            $i = sprintf("%s %02d:%02d:%02d\"", arr[1], arr[2], arr[3], arr[4])
        }
    }
    print
}' OFS=, input.txt

Entrada

"12345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","15/12/2017 4:26:00 PM"
"22345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","16/12/2017 6:26:00 AM"
"32345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","17/12/2017 10:00:00 PM"
"42345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","18/12/2017 11:26:00 AM"
"52345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","19/12/2017 2:26:00 PM"

Resultado

"12345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","15/12/2017 16:26:00"
"22345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","16/12/2017 06:26:00"
"32345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","17/12/2017 22:00:00"
"42345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","18/12/2017 11:26:00"
"52345","BLAH","DEDA","0.000","1.111","2.22222","3.3333333","19/12/2017 14:26:00"
    
por 28.02.2018 / 20:17