Comando Awk para substituir uma substring por um valor específico

Comando Awk para substituir uma substring por um valor específico

Eu tenho um arquivo simples que tem um número de telefone no campo começando na posição 314 até 323. Agora eu queria simular esse campo com 1234567890.

Para isso tentei usar os comandos abaixo e ambos estão gerando erro:

awk '{var=substr($0,314,10);gsub("[0-9]","1234567890",$var); print}' final_phone.txt >final_phone.txt1

fatal: grow_fields_arr:fields_arr: não é possível alocar 9849885432 bytes de memória (não é possível alocar memória)

No segundo caso

awk 'var=substr($0,314,10) { var = "1234567890" }1' final_phone.txt >final_phone.txt1

Isso funcionou, mas os valores não mudaram. A saída permaneceu a mesma.

Alguém pode me ajudar com a sintaxe aqui?

No primeiro caso tentei atribuir a substring a uma variável e gsub()queria verificar o padrão de números e substituir por 1234567890.

alguém poderia me ajudar com isso

Responder1

você precisa imprimir duas substrings, uma parte antes dessa posição e outra parte depois dessa posição, algo como:

$ awk -v dummy='0123456789' -v start=314 -v len=10 '
{ print substr($0, 1, start-1) dummy substr($0, start+len) }' infile >outfile

testando:

$ awk -v dummy='0123456789' -v start=4 -v len=10 '
{ print substr($0, 1, start-1) dummy substr($0, start+len) }' <<<'0009876543210999'
0000123456789999

Problema com seu comando:

  1. você está usando $varem vez de varno terceiro argumento para gsub(), pois resulta gsub() para procurar um campo cujo número é o valor do varqual é um número de campo de comprimento de 10 dígitos, então awk tenta gsub() nesse campo #xxxxxxxxxx mas falha devido à alocação de memória para reavaliar esse grande número de campos (porque ao usar qualquer campo diferente $0do terceiro argumento do gsub() ele força o awk a reconstruir os campos de volta no OFS padrão).

  2. se corrigirmos o problema nº 1, você substituirá todos os dígitos da varvariável por 1234567890string.

  3. você o usou printpara imprimir a linha atual sem alterações, já que você não faz nenhuma atualização nela.

Responder2

Você pode usar sedem vez de awkqual será menos detalhado:

$ sed -E 's/^(.{313})[0-9]{10}/\10123456789/' infile
<313 chars>1234567890

Responder3

Você poderia usar perl em vez de awk. por exemplo

perl -p -e 'substr($_,313,10) = "1234567890"' final_phone.txt >final_phone.txt1

NOTA: na função do Perl substr, os deslocamentos começam em 0 em vez de 1 - então o deslocamento 313 é o 314º caractere. Veja perldoc -f substrpara detalhes.

informação relacionada