He escrito un comando awk
awk 'NR==5 {sub(substr($1,14,1),(substr($1,14,1) + 1)); print "test.py"}' > test.py
Esto está tratando de cambiar el carácter 14 en la línea 5 de un archivo python. Por alguna razón, esto no deja de ejecutarse y tengo que romperlo. También elimina el contenido del archivo.
Ejemplo de entrada:
import tools tools.setup( name='test', tagvisc='0.0.8', packages=tools.ges(), line xyz )`
Producción:
import tools tools.setup( name='test', tagvisc='0.0.9', packages=tools.ges(), line xyz )Si entiendo los matices de lo que debe hacer ahora, deberá dividir el primer campo del quinto registro en una matriz usando "." como campo y luego elimine "\"," del final del tercer elemento de la matriz (opcional) antes de incrementar el número y volver a unir el campo. Puede hacerlo con:
awk '{split($1,a,"."); sub(/["],/,"",a[3]); $1=a[1]"."a[2]"."(a[3]+1)"\","}1' ( NR==5 omitido por ejemplo)
Ejemplo de uso/resultado
$ echo 'tagvisc="3.4.30"', | awk '{split($1,a,"."); sub(/["],/,"",a[3]); $1=a[1]"."a[2]"."(a[3]+1)"\","}1' tagvisc="3.4.31",Dejaré la redirección a un archivo temporal y luego volveré al original. Avísame si esto no es lo que necesitas.
Sumando NR == 5 tendrías
awk 'NR==5 {split($1,a,"."); sub(/["],/,"",a[3]); $1=a[1]"."a[2]"."(a[3]+1)"\","}1' test.py > tmp; mv -f tmp test.pyAléjese del número de línea fijo ( NR==5 ) y la posición del carácter fijo ( 14 ) y, en su lugar, busque dinámicamente lo que desea cambiar/incrementar, por ejemplo:
$ cat test.py import tools tools.setup( name='test', tagvisc='0.0.10', packages=tools.ges(), line xyz ) Una idea awk para incrementar el 10 (tercera línea, tercera cadena numérica en línea):
awk ' /tagvisc=/ { split($0,arr,".") # split line on periods sub("." arr[3]+0 "\047","." arr[3]+1 "\047") # replace .<oldvalue>\047 with .<newvalue>\047; \047 == single quote } 1 ' test.pyNOTAS:
arr[3] = 10', ; con arr[3]+0 awk tomará el contenido numérico más a la izquierda, eliminará todo lo demás, luego agregará 0 , dejándonos con arr[3] = 10 ; la misma lógica se aplica para arr[3]+1 ( arr[3]+1 = 11 ); básicamente un truco para descartar cualquier sufijo que no sea numéricotagvisc='xyz' , esto cambiará z en todas las líneas; podemos solucionar esto agregando algo más de lógica para cambiar solo la first aparición, pero lo dejaré fuera por ahora, asumiendo que no es un problemaEsto genera:
import tools tools.setup( name='test', tagvisc='0.0.11', packages=tools.ges(), line xyz )Si el objetivo es sobrescribir el archivo original con los nuevos valores, tiene un par de opciones:
# use temporary file: awk '...' test.py > tmp ; mv tmp test.py # if using GNU awk, and once accuracy of script has been verified: awk -i inplace '...' test.pyUsando awk para realizar cambios en el carácter n en la línea [mth] en un archivo :
$ awk 'BEGIN{FS=OFS=""}NR==5{$18=9}1' file # > tmp && mv tmp fileSalidas:
import tools tools.setup( name='test', tagvisc='0.0.9', <----- this is not output but points to what changed packages=tools.ges(), line xyz )Explicado:
$ awk ' BEGIN { FS=OFS="" # set the field separators to empty and you can reference } # each char in record by a number NR==5 { # 5th record $18=9 # and 18th char is replaced with a 9 }1' file # > tmp && mv tmp file # output to a tmp file and replace Aviso: algunos awks (probablemente todos excepto GNU awk) fallarán si intenta reemplazar un carácter multibyte por uno de un solo byte (por ejemplo, utf8 ä (0xc3 0xa4) con a (0x61) resultará en 0x61 0xa4). Naturalmente, una ä antes de la posición que desea reemplazar hará que sus cálculos se desplacen en 1.
Ah, sí, puede reemplazar un carácter con varios caracteres, pero no al revés.