Seria possível usar sed
para isso, mas awk
é mais natural:
awk -F'"' -v OFS='"' '$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)} 1' input.json
{"_id":"","timestamp":"2015-04-20T01:30:55-0700"}
{"_id":"","timestamp":"2015-04-20T01:32:25-0700"}
{"_id":"","timestamp":"2015-04-20T01:35:39-0700"}
Os itens acima mostram um deslocamento de -7: 00 horas. Isso reflete o fuso horário padrão do sistema. Alterar a variável do shell TZ
mudará o padrão.
Como funciona
-
-F'"' -v OFS='"'
Isso define os separadores de campos de entrada e saída como
"
. -
$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)}
Com
"
como o separador de campo, a data é o campo número 8. Isso cria uma cadeia com o comandodate
correto e, em seguida, executa o comando que captura a saída em um campo atualizado 8.O
$8
na frente significa que esta parte só será executada se houver um valor não vazio para o campo 8. Isso permite, por exemplo, que linhas vazias passem sem ser molestadas. -
1
Esta é a abreviada enigmática de awk para "imprimir esta linha".
Manipulação de citações duplas extras
Como estamos usando "
como o separador de campo. Suponha que haja um número variável de "
antes do registro de data e hora. Nesse caso, precisamos nos referir ao timestamp como o segundo último campo, $(NF-1)
, em vez do oitavo campo, $8
. Neste caso:
awk -F'"' -v OFS='"' '$8 {cmd="date -d \""$(NF-1)"\" +%FT%T%z"; cmd | getline $(NF-1); close(cmd)} 1' input.json
Adicionando formatação personalizada ao campo de data
$ awk -F'"' -v OFS='"' '$8 {cmd="date -d \""$(NF-1)"\" +%FT%T%z"; cmd | getline $(NF-1); close(cmd);$(NF-1)="{$date:" $(NF-1) "}"} 1' input.json
{"_id":"","timestamp":"{$date:2015-04-20T01:30:55-0700}"}
{"_id":"","timestamp":"{$date:2015-04-20T01:32:25-0700}"}
{"_id":"","timestamp":"{$date:2015-04-20T01:35:39-0700}"}