Truncar as vírgulas à direita de cada linha com base no primeiro campo em um arquivo delimitado

2

Eu preciso remover as vírgulas à direita com base no record_type (primeiro campo). O arquivo de entrada tem 50 delimitadores, preciso reduzi-los com base no tipo de registro. Se o 1º campo for 400, remova os 10 últimos delimitadores, se 300 remover 5 delimitadores, se 210 remover 2 vírgulas. O padrão de 400, 300 e 210 repete e a ordem tem que ser mantida.

Por exemplo:

400,"100.00",,,,"31",,,,"510","410","0102","023",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
300,"110","1",,"2016-04-15",,,"52706","TESTFR1","100.00","1.00",,,"N",,,,,,,,,
210,"6876262",,"23 Rue du Roule",,,"PARIS","DF","75001","FR",,,,,,,,,,,,,,,,,,

Eu preciso da saída como

400,"100.00",,,,"31",,,,"510","410","0102","023",,,,,,,,,,,,,,,,,,,,
300,"110","1",,"2016-04-15",,,"52706","TESTFR1","100.00","1.00",,,"N",,,,
210,"6876262",,"23 Rue du Roule",,,"PARIS","DF","75001","FR",,,,,,,,,,,,,,,,

Eu tentei o awk e o sed, mas eles estão truncando o arquivo inteiro.

    
por sata 18.01.2017 / 22:51

3 respostas

3

Sed pode atender às suas necessidades. Isso corresponderá ao início desejado da string e, em seguida, removerá o número desejado de vírgulas do final.

sed -e '/^400/ s/,\{10\}$//' -e '/^300/ s/,\{5\}$//' -e '/^210/ s/,\{2\}$//' 
    
por 18.01.2017 / 23:19
1

abordagem AWK. Definimos a função trunk para imprimir uma subcadeia de caracteres da linha inteira, do índice 0 ao comprimento do índice - n caracteres. O resto é simplesmente correspondência de padrões e chamar a função trunk com o número apropriado de caracteres a serem removidos.

Como um revestimento:

$ awk -F ',' 'function trunk(n){print substr($0,0,length($0)-n)}; $1==400{trunk(10)};$1==300{trunk(5)};$1==210{trunk(2)} ' input.txt 

De um script, isso seria assim:

#!/usr/bin/awk -f

BEGIN { FS="," };

function trunk(n){
    print substr($0,0,length($0)-n)
}; 

$1==400{ trunk(10)};
$1==300{trunk(5)};
$1==210{trunk(2)};

E aqui está em ação:

$ ./trunk_lines.awk input.txt                                                                                            
400,"100.00",,,,"31",,,,"510","410","0102","023",,,,,,,,,,,,,,,,,,,,
300,"110","1",,"2016-04-15",,,"52706","TESTFR1","100.00","1.00",,,"N",,,,
210,"6876262",,"23 Rue du Roule",,,"PARIS","DF","75001","FR",,,,,,,,,,,,,,,,
    
por 18.01.2017 / 23:58
1

Dado que os campos à direita estão vazios (ou se você quiser excluí-los também)

awk -F, -vOFS=, '$1=="400"{NF-=10} $1=="300"{NF-=5} $1=="210"{NF-=2} 1' file 

ou se você quiser ser inteligente (o que pode ser bom e ruim)

awk -F, -vOFS=, 'BEGIN{x[400]=10;x[300]=5;x[210]=2} {NF-=x[$1]} 1' file
    
por 18.01.2017 / 23:59