Eu preciso adicionar dois campos a um arquivo csv. O separador dos campos csv é o comma
, e alguns campos estão entre aspas duplas. O problema é que, dentro dos campos com aspas duplas, é possível encontrar também uma vírgula. Como dividir isso com awk?
Os campos resultam de uma exportação do mongo. A posição desses campos pode mudar,
Csv de entrada de amostra,
DateTime,Dealers,Locations,CallEndTime,TotalDuration
"2018-12-27 12:19:14","Dealer1,Dealer2,Dealer3","Gujarat",,67,,
"2018-12-27 12:19:14","Dealer1,Dealer2","Gujarat,Vadodara",,100,
Csv de saída de amostra,
DateTime,Dealers,Locations,CallEndTime,TotalDuration
"2019-01-07 11:35:42","Dealer1,Dealer2,Dealer3","Gujarat","2019-01-07 11:36:51",69,,
"2018-12-27 12:19:14","Dealer1,Dealer2","Gujarat,Vadodara","2018-12-27 12:19:14,78",
Código awk:
BEGIN { FSOFS=","}
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
NR>1 {
begSecs = mktime( gensub( /[":-]/, " ", "g", $(f["DateTime"]) ) )
endSecs = begSecs + $(f["TotalDuration"])
$(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}
{print}
Eu não quero considerar as vírgulas dentro das aspas duplas como FS, vi que isso pode ser feito usando FPAT, mas não tenho idéia de como usar isso aqui no caso,
BEGIN { FPAT = "([^,]*)|(\"[^\"]+\")"}
NR==1 {
for (i=1; i<=NF; i++) {
f[$i] = i
}
}
NR>1 {
begSecs = mktime( gensub(/[":-]/," ","g",$(f["DateTime"])) )
endSecs = begSecs + $(f["TotalDuration"])
$(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}
{print}
Eu não usaria
awk
para analisar arquivos csv, melhor usar ferramentas dedicadas, por exemplo, usando o módulo python csv:output.csv:
Com csvkit >= 1.0.4 (versão de desenvolvimento atual) você pode usar
csvsql
:Seu segundo exemplo quase funciona. Você está apenas faltando um
,
como separador de saída (OFS=","
) e colocar aspas duplas em torno da nova data calculada. Isso funciona:Para os exemplos dados.
Mas há muito mais sobre o csv do que o awk pode suportar. Como outras respostas já recomendaram, use uma ferramenta que entenda o formato csv corretamente.
Por exemplo, para extrair todos os valores e substituir as vírgulas separadoras por
--
:Saída de exemplo:
FS
define o delimitador de campo, ou seja, define o que um campo não é .FPAT
, por outro lado, define o que é um campo .Aliás, a primeira linha em seu exemplo input.csv tem 6 valores, enquanto a segunda linha e a linha de cabeçalho sugerem que deve haver 5 colunas.