Edição de texto em um ponto específico em cada linha de um arquivo de texto

4

Eu tenho um arquivo de texto contendo uma lista de números de nove dígitos como este:

550411876
550425175
550426504

E um segundo arquivo de texto que contém uma única linha como esta:

09Y20171031    13415520171031    134155AP|AO|ABxxxxxxxxx|AC|CH|BIN|

Eu preciso criar um arquivo de texto que contenha muitas ocorrências da linha do segundo arquivo, mas com o xxxxxxxxx substituído pelo número do primeiro arquivo (o xxxxxxxxx está literalmente no arquivo, não é apenas um exemplo). Neste caso, o resultado seria:

09Y20171031    13415520171031    134155AP|AO|AB550411876|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550426504|AC|CH|BIN|

Como faço isso no Linux?

    
por Jaz 31.10.2017 / 14:57

5 respostas

6

Supondo que os números estão no arquivo numbers e que o arquivo de modelo que você gostaria de usar é file :

awk -F'|' -v OFS='|' 'NR==FNR { n[++i] = $0; next } { for (i in n) { $3 = substr($3,1,2) n[i]; print } }' numbers file

Isso primeiro lerá os números na matriz n e, em seguida, para o arquivo de modelo, use os dois primeiros caracteres do terceiro campo | -delimited, concatene isso com os números da matriz n e imprima o resultado uma vez para cada número.

As opções -F'|' -v OFS='|' garantem a leitura e gravação dos dados como | -delimited.

Em seguida, basta redirecionar a saída disso para um novo arquivo.

Isso não depende do modelo para conter xxxxxxxxx .

Teste:

$ cat file
09Y20171031    13415520171031    134155AP|AO|AB something something|AC|CH|BIN|

$ awk -F'|' -v OFS='|' 'NR==FNR { n[++i] = $0; next } { for (i in n) { $3 = substr($3,1,2) n[i]; print } }' numbers file
09Y20171031    13415520171031    134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550426504|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550411876|AC|CH|BIN|

Uma abordagem bash -only (sem utilitários externos) que usa os nove x -es:

template=$(<file)
while read number; do
    printf '%s\n' "${template//xxxxxxxxx/$number}"
done <numbers
    
por 31.10.2017 / 15:21
5

Aparentemente, seu modelo tem apenas uma linha ...

Se isso for verdade, podemos

for a in $(< list)
do
    printf "09Y20171031    13415520171031   134155AP|AO|AB%s|AC|CH|BIN|\n" $a
done
    
por 31.10.2017 / 15:51
3

Outra abordagem awk :

awk 'NR==FNR{ a[++c]=$1; next }
     { for(i in a) { r=$0; sub(/x{9}/,a[i],r); print r } }' file1 file2
  • a[++c]=$1 - capturando números da file1 na matriz a

  • for(i in a) - iterando por números de nove dígitos

  • sub(/x{9}/,a[i],r) - substitua a sequência crucial xxxxxxxxx pelo número seguinte contido em a[i]

A saída:

09Y20171031    13415520171031    134155AP|AO|AB550411876|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550426504|AC|CH|BIN|
    
por 31.10.2017 / 15:22
3

com list sendo a lista de números e tmpl sendo o arquivo de modelo

for y in $(< list )
do
   sed -r -s s/[x]{9}/$y/ < tmpl
done

09Y20171031    13415520171031    134155AP|AO|AB550411876|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031    13415520171031    134155AP|AO|AB550426504|AC|CH|BIN|

onde

  • for y in $(< list ) leu cada linha e colocou o valor na variável y
  • sed -r use extensão do gnu
  • -e s/[x]{9}/../ substitui 9 ocorrências do caractere x ...
  • ../$y/ ... pelo conteúdo do var y

você terá que redirecionar o loop para um arquivo

done > my_file
    
por 31.10.2017 / 15:21
1

Perl não pode faltar aqui.

p=$(< pat) perl -nlE'$l = $ENV{p}; $n=$_; $l =~ s/x{9}/$n/; say $l if /./' nums

pat é o nome do arquivo padrão

p é uma variável de ambiente que transporta o padrão

n é uma variável Perl contendo o número em cada iteração

l contém linha (primeiro o padrão para cada linha, depois da substituição a linha atual a ser impressa)

nums é o nome do arquivo de números

    
por 31.10.2017 / 16:20