Com um único awk
:
awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
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.
Com um único awk
:
awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
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
)
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
$
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
$ 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).
Tags text-processing awk sed cut csv-simple