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 comandodatecorreto e, em seguida, executa o comando que captura a saída em um campo atualizado 8.O
$8na 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. -
1Esta é 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}"}