Awk para leer el file de lectura

Todavía no he llegado al awk pero está en mi plato para aprender este año. Hice una pregunta previa que me hizo pensar y funciona. Sin embargo, no estoy seguro de cómo ingresar todos los types de files y generar el tipo de file con el nombre exacto en awk . Ejemplo:

  • encuentra todos los files .xml
  • localiza file.xml
  • hace awk script
  • guardado como file.xml

Investigué awk in bash y encontré esto, pero no creo que vaya a resolver el problema de la actual printing del código awk en un file .xml . Para que actualmente ejecute el script, tengo que hacer gawk -f file.sh < file.xml .

Mi objective sería search todos los files .xml , ejecutar código y save en la misma location el nuevo file .xml .

EDITAR: Pude hacer que devolviera a xml después de algunas búsquedas más con esto:

 gawk -f awk.sh < file.xml > file.xml 

Si no te importa utilizar otra herramienta, también debes investigar el command find , en particular la opción -exec, o combinarla con el command xargs . (También investigue find ... -print0 | xargs -0 ... )

Tienes varios problemas para resolver.

Como mínimo, tendrá que darle a su script AWK una list de files, ya que no tiene una manera incorporada de search directorys. Esto se puede hacer más fácilmente y obviamente por el shell, o por find . Hay varias maneras diferentes de entregar la list a AWK también.

También deberá tener cuidado de sobrescribir únicamente el file original si su secuencia de commands ha procesado correctamente sus contenidos y guardado el resultado en un file temporal.

También tendrá que pensar mucho sobre lo que intenta hacer con estos files XML. XML (y todos los "lenguajes" similares a SGML) tiene una syntax atrozmente difícil de analizar.

Si comienza con el último problema primero y logra crear un script simple que efectivamente será un progtwig de filter que procesará un file de input que se le asignó en la input estándar, escribiendo los resultados en salida estándar, entonces habrá resuelto el paso más importante , y puede probarlo simplemente con la networkingirección de files en la command-line como ya habrá adivinado, pero deberá tener mucho cuidado de no sobreescribir o truncar sus files de input:

 awk -f script.awk < input_file > output_file 

Un simple fragment de syntax del shell le ayudará a transformar el file de input al renombrar el file de salida con el mismo nombre IFF que el script tiene éxito (resolviendo así el segundo problema):

 awk -f script.awk < input_file > output_file && mv output_file input_file 

El command después de && se ejecutará solo si el command antes de ejecutarse y sale con un estado de éxito (un código de salida de 0 .

Ahora puedes finalmente resolver ese primer problema al tratar con una gran cantidad de files. La forma más sencilla de repetir los commands anteriores sobre una list de files sería usar un pequeño bucle de shell simple que lee un nombre de file a la vez y lo procesa utilizando el command anterior:

 while read fn; do awk -f script.awk < "${fn}" > "${fn}.out" && mv "${fn}.out" "${fn}" || break done 

El || break || break hará que el ciclo termine si el process awk falla, dejando un file .out parcial para el file fallido. Tenga en count también la cita cuidadosa de las expansiones de variables: esto asegura que los nombres de files que contienen espacios en blanco se manejen correctamente.

Ahora que el ciclo de while read , por supuesto, solo esperará a que escriba un nombre de file, luego otro, etc., hasta que lo interrumpa o le envíe un carácter EOF. Entonces, simplemente podría darle una list de nombres de files usando find , así:

 find . -name '*.xml' -print | while read fn; do 

….

Puede envolver todo esto en un pequeño script, o simplemente escribirlo en la línea de command.

Si realiza un pequeño script de shell, entonces podría alternativamente hacer que el ciclo while itere sobre la list de parameters de command-line y tratar cada uno como un nombre de file para procesar. De esta forma, podría usar la expansión de nombre de file de shell para generar la list de files para procesar, como es típico de muchos progtwigs Unix que procesan lists de files proporcionados en la línea de command. Entonces usarías un ciclo for como este:

 for fn do 

….

(¡Tenga en count que no hay punto y coma después del nombre de la variable en la primera línea!)

También puede modificar su secuencia de commands AWK para leer una list de nombres de files de la input estándar, y cambiar el nombre del file de salida usando la function system() para llamar a mv .