Comando awk para reemplazar una subcadena con un valor específico

Comando awk para reemplazar una subcadena con un valor específico

Tengo un archivo plano que tiene un número de teléfono en el campo que comienza en la posición 314 hasta la 323. Ahora quería simular ese campo con 1234567890.

Para esto, intenté usar los siguientes comandos y ambos arrojan un error:

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

fatal: grow_fields_arr: campos_arr: no se pueden asignar 9849885432 bytes de memoria (No se puede asignar memoria)

en el segundo caso

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

Esto funcionó pero los valores no cambiaron. La producción siguió siendo la misma.

¿Alguien puede ayudarme con la sintaxis aquí?

En el primer caso, intenté asignar la subcadena a una variable y gsub()quería verificar el patrón de números y sustituirlo por 1234567890.

Puede alguien ayudarme con esto

Respuesta1

necesitas imprimir dos subcadenas, una parte antes de esa posición y otra parte después de esa posición, 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

pruebas:

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

Problema con su comando:

  1. está utilizando $varen lugar de varen el tercer argumento de gsub(), ya que resulta gsub() para buscar un campo cuyo número es el valor del varcual es un número de campo de 10 dígitos de longitud, por lo que awk intenta gsub() en ese campo #xxxxxxxxxx pero falla debido a la asignación de memoria para reevaluar esta gran cantidad de campos (porque cuando se usa cualquier campo que no sea $0el tercer argumento de gsub(), obliga a awk a reconstruir los campos nuevamente en el OFS predeterminado).

  2. Si solucionamos el problema n.° 1, reemplazará todos los dígitos de la varvariable con 1234567890una cadena.

  3. Luego lo usó print, imprimirá la línea actual sin cambios, ya que no realiza ninguna actualización al respecto.

Respuesta2

Puedes usar seden lugar de awkcuál será menos detallado:

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

Respuesta3

Podrías usar perl en lugar de awk. p.ej

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

NOTA: en la función de Perl substr, las compensaciones comienzan desde 0 en lugar de 1, por lo que la compensación 313 es el carácter 314. Ver perldoc -f substrpara más detalles.

información relacionada