linux - print - awk separador de campos
awk guardar modificaciones en su lugar (8)
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 |
.
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 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
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
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
solo un pequeño truco que funciona
echo "$(awk ''{awk code}'' file)" > file
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 answer correcta.
Esto no puede funcionar:
someprocess < file > file
El shell realiza las redirecciones antes de pasar el control a algún proceso ( redirections ). 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.