¿Es posible usar gawk
la -i inplace
opción y también imprimir cosas stdout
?
Por ejemplo, si quisiera actualizar un archivo, y si hay algún cambio, imprima el nombre del archivo y las líneas cambiadas, stderr
podría hacer algo como
find -type f -name 'myfiles' -exec gawk -i inplace '{if(gsub(/pat/, "repl")) { print FILENAME > "/proc/self/fd/2" ; print > "/proc/self/fd/2"; } print;}' {} +
pero, ¿hay alguna forma de usarla stdout
o una forma más limpia de imprimir ese bloque en la secuencia alternativa?
find -type f -name 'myfiles' -exec grep -q 'pattern' {} \; -print -exec gawk -i inplace '{do_your_sub_and_print_to_dev/stderr_too}' {} \;
, solo usará awk para editar los archivos que realmente contienen líneas que coinciden con ese patrón.grep
puede ser. Mi primer instinto es evitar tener que "procesar" el archivo dos veces, pero no me sorprendería en absoluto si de todos modos es más rápido. Simplemente muestra por qué puedo confiar en mi instinto en las tareas de creación de perfiles-print -exec gawk
ya no se ejecuta) y 2) se detendrá en la primera coincidencia, a menos que la primera coincidencia esté en el última línea todavía no está procesando todo el archivo dos veces (es más como 1.X veces). Además, sigawk -i inplace
funciona asísed -i
, editará el archivo en el lugar de todos modos, es decir, actualizar las marcas de tiempo, el inodo, etc., incluso si no hubiera nada que editar ...Respuestas:
Deberías usar
/dev/stderr
o en/dev/fd/2
lugar de/proc/self/fd/2
.gawk
maneja/dev/fd/x
y/dev/stderr
por sí mismo (independientemente de si el sistema tiene esos archivos o no).Cuando haces un:
gawk
hace unwrite(2, "x\n")
, mientras que cuando haces:ya que no trata
/proc/self/fd/x
especialmente, hace un:Primero
/proc/self/fd
es específico de Linux y en Linux son problemáticos. Las dos versiones anteriores no son equivalentes cuando stderr corresponde a un archivo normal u otro que se puede buscar o a un socket (para el cual este último fallaría) (sin mencionar que desperdicia un descriptor de archivo).Dicho esto, si necesita escribir en el stdout original, debe guardarlo en otro archivo como:
gawk
redirecciona stdout con in situ al archivo. Es necesario porque, por ejemplo, querrías:para almacenar la
uname
salida en elfile
.fuente
Sólo por diversión, un enfoque alternativo utilizando sólo cuenta con POSIX de
find
,sh
,grep
y (sobre todo)ex
:(Todos los saltos de línea en el comando anterior son opcionales; se puede condensar en una sola línea).
O, posiblemente más legible:
:)
(Este comando no ha sido probado; las ediciones son bienvenidas si hice alguna tontería).
fuente