awk: divide a coluna, imprime o lado esquerdo do delimitador e cola no meio do csv

2

Arquivo de entrada:

AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

O resultado deve ser:

AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Eu pensei em algo como:

awk -F, '{n=split($2,a,":"); a[n]} {$2=$NF","$2}1' OFS=,

Mas o primeiro "split" usa o lado direito do delimitador em vez do esquerdo e a cópia no final copia o HHH em vez do BBB.

    
por T-One 31.08.2018 / 12:00

5 respostas

2

Com um único awk :

awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
    
por 31.08.2018 / 12:57
0

Tente isto:

awk -F, '{n=split($2,a,":"); a[n]} {$2=a[1]","$2}1' OFS=, file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

A atribuição do último campo e um segundo campo a $ 2 ( $2=$NF","$2 ) em vez de atribuir a divisão em a com o segundo campo ( $2=a[1]","$2 )

    
por 31.08.2018 / 12:10
0

Uma abordagem simples não-awk

$ ( cut -f1 -d: file ; cut -f2- -d, file ) | paste -sd,
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
$
    
por 31.08.2018 / 12:33
0

Uma rápida opção sed

sed -r 's/, \w+/&&/'

A expressão \w+ corresponde a alfanuméricos (no seu exemplo, o BBB ), mas não a pontuação ou espaço em branco. O & representa a correspondência inteira.

Exemplo

echo 'AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH' | sed -r 's/, \w+/&&/'
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
    
por 31.08.2018 / 13:14
0
$ awk -F, -v OFS=, '{ for (i=1; i<=NF; ++i) if (split($i, a, ":") > 1) $i = a[1] OFS $i } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Você terá que fazer uma iteração em todos os campos e, quando encontrar um campo que se divida em mais de uma string ao dividir em : , será necessário preceder a primeira parte dessa string dividida ao valor dessa campo.

Se você sabe que sempre será o segundo campo:

$ awk -F, -v OFS=, '{ split($2, a, ":"); $2 = a[1] OFS $2 } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Em seu código, n será o número de sequências de caracteres nas quais os dados foram divididos. Portanto, a[n] será a última string% (mais à direita) : -eliminada em $2 .

Usando sed :

$ sed 's/\([^,: ]*\):/, &/g' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Isso substituirá qualquer string que não contenha , , : ou espaço, e que sejam seguidos imediatamente por um : com ela mesma duas vezes (a segunda vez com o% final: incluído).

Remova o g no final do comando s se você espera apenas fazer uma única substituição (como no seu exemplo).

    
por 31.08.2018 / 12:08