awk guardar modificaciones en su lugar

Estoy aprendiendo awk y me gustaría saber si hay una opción para escribir cambios en el archivo, similar a sed donde usaría la opción -i para guardar modificaciones en un archivo.

Entiendo que podría usar la redirección para escribir cambios. Sin embargo, ¿hay una opción en awk para hacer eso?

En la última versión de GNU Awk (desde que salió 4.1.0 ), tiene la opción de editar archivos “in situ” :

[…] La extensión “in situ”, construida usando la nueva instalación, se puede usar para simular la función ” sed -i ” de GNU. […]

Ejemplo de uso:

 $ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3 

Para mantener la copia de seguridad:

 $ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") } > { print }' file1 file2 file3 

A menos que tengas GNU awk 4.1.0 o posterior …

No tendrá una opción como la opción -i de sed, sino que:

 $ awk '{print $0}' file > tmp && mv tmp file 

Nota: el -i no es mágico, también está creando un archivo temporal sed solo lo maneja por ti.


A partir de GNU awk 4.1.0 …

GNU awk agregó esta funcionalidad en la versión 4.1.0 (publicada el 10/05/2013) . No es tan directo como simplemente dar la opción -i como se describe en las notas publicadas:

La nueva opción -i (de xgawk) se utiliza para cargar archivos de biblioteca awk. Esto difiere de -f en que el primer argumento no opcional se trata como un script.

inplace.awk utilizar el paquete inplace.awk include file para invocar la extensión correctamente así:

 $ cat file 123 abc 456 def 789 hij $ gawk -i inplace '{print $1}' file $ cat file 123 456 789 

La variable INPLACE_SUFFIX se puede utilizar para especificar la extensión de un archivo de copia de seguridad:

 $ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file $ cat file 123 456 789 $ cat file.bak 123 abc 456 def 789 hij 

Estoy contento de que se haya agregado esta característica, pero para mí la implementación no es muy incómoda, ya que el poder está en la concisión del lenguaje y, en su -i inplace hay 8 caracteres para OMI de largo.

Aquí hay un enlace al manual de la palabra oficial.

@sudo_O tiene la respuesta correcta.

Esto no puede funcionar:

 someprocess < file > file 

El shell realiza las redirecciones antes de pasar el control a algún proceso ( redirecciones ). La > redirección truncará el archivo a tamaño cero ( redirigiendo la salida ). Por lo tanto, cuando se inicia algún proceso y quiere leer del archivo, no hay datos para leer.

solo un pequeño truco que funciona

 echo "$(awk '{awk code}' file)" > file 

Una alternativa es usar sponge :

 awk '{print $0}' your_file | sponge your_file 

Donde reemplaza '{print $0}' por su script awk y your_file por el nombre del archivo que desea editar en su lugar.

sponge absorbe completamente la entrada antes de guardarla en el archivo.

lo siguiente no funcionará

 echo $(awk '{awk code}' file) > file 

Esto debería funcionar

 echo "$(awk '{awk code}' file)" > file 

Usando tee

  awk '{awk code}' file | tee file 

el comando tee tiene lugar y se ejecuta después de que finalice el comando awk debido a | .

¡En caso de que quiera una solución solo de awk sin crear un archivo temporal y utilizable con la versión! = (Gawk 4.1.0):

 awk '{a[b++]=$0} END {for(c=0;c< =b;c++)print a[c]>ARGV[1]}' file