Corrigindo CSV malformado com novos caracteres de linha incorretos usando somente sed ou perl

0

Eu tenho um arquivo CSV delimitado por vírgula, mas por algum motivo nosso sistema insere um novo caractere de linha em um local aleatório no arquivo, o que faz com que o arquivo inteiro seja quebrado. Eu posso pegar o número de colunas no arquivo.

Como posso resolvê-lo com sed e / ou perl em um comando de um liner? Eu sei que é solucionável com awk , mas isso é para fins de aprendizado. Se estiver usando perl , não quero usar as funções CSV internas. É solucionável? Eu estou neste problema há vários dias eu não consigo encontrar uma solução: (

Exemplo de entrada mal formada (muitos inseridos aleatoriamente \ n)

policyID,statecode,county,Point longitude,Some Thing Here,point_granularity
119736,FL,CLAY COUNTY,-81.711777,“Residential Lot”,1
448094,FL,CLAY COUNTY,-81.707664,“Residen
tial Lot”,3
206893,FL,CLAY COUNTY,-81.7
00455,“Residen
tial Lot”,1
333743,FL,CLAY COUNTY,-81.707703,“Residential Lot”,
3
172534,FL,CLAY COUNTY,-81.702675,“Residential Lot”,1
785275,FL,CLAY COUNTY,-81.707703,“Residential Lot”,3
995932,FL,CLAY COUNTY,-81.713882,
“Residential Lot”,1
223488,FL,CLAY COUNTY,-81.707146,“Residential Lot”,1
4335
12,FL,CLAY COUNTY,-81.704613,
“Residential Lot”,1

Saída obrigatória

policyID,statecode,county,Point longitude,Some Thing Here,point_granularity
119736,FL,CLAY COUNTY,-81.711777,“Residential Lot”,1
448094,FL,CLAY COUNTY,-81.707664,“Residential Lot”,3
206893,FL,CLAY COUNTY,-81.700455,“Residential Lot”,1
333743,FL,CLAY COUNTY,-81.707703,“Residential Lot”,3
172534,FL,CLAY COUNTY,-81.702675,“Residential Lot”,1
785275,FL,CLAY COUNTY,-81.707703,“Residential Lot”,3
995932,FL,CLAY COUNTY,-81.713882,“Residential Lot”,1
223488,FL,CLAY COUNTY,-81.707146,“Residential Lot”,1
433512,FL,CLAY COUNTY,-81.704613,“Residential Lot”,1
    
por Harry McKenzie 02.04.2018 / 08:28

2 respostas

1
$ awk -F, '{ while (NF < 6 || $NF == "") { brokenline=$0; getline; $0 = brokenline $0}; print }' file.csv
policyID,statecode,county,Point longitude,Some Thing Here,point_granularity
119736,FL,CLAY COUNTY,-81.711777,“Residential Lot”,1
448094,FL,CLAY COUNTY,-81.707664,“Residential Lot”,3
206893,FL,CLAY COUNTY,-81.700455,“Residential Lot”,1
333743,FL,CLAY COUNTY,-81.707703,“Residential Lot”,3
172534,FL,CLAY COUNTY,-81.702675,“Residential Lot”,1
785275,FL,CLAY COUNTY,-81.707703,“Residential Lot”,3
995932,FL,CLAY COUNTY,-81.713882,“Residential Lot”,1
223488,FL,CLAY COUNTY,-81.707146,“Residential Lot”,1
433512,FL,CLAY COUNTY,-81.704613,“Residential Lot”,1

O código awk anexará a próxima linha de entrada à linha atual enquanto houver menos de seis campos na linha atual, ou o último campo estiver vazio (há uma linha quebrada logo após o último separador de campo).

Um Perl funciona:

perl -ne 'chomp;while (tr/,/,/ < 5 || /,$/) { $_ .= readline; chomp } print "$_\n"' file.csv
    
por 02.04.2018 / 09:41
0

Como dizem Kusalananda, existem 6 campos em cada linha, então você pode tentar este gnu sed.

sed -E ':A;h;s/^/,/;s/((,[^,]+){6})(.*)//;/./{g;N;s/\n//;bA};g' infile
    
por 02.04.2018 / 12:22