Archivos de texto asombrados

Algunas herramientas en una caja de herramientas son versátiles. Puede usar un destornillador como una varilla pálida para abrir una tabla de pintura, por ejemplo. Incluso golpeé una cuerda con un destornillador, aunque probablemente no deberías. Pero una motosierra no es tan versátil. Simplemente corta. ¡Pero un hombre lo corta!

AWK es una motosierra para procesar archivos de texto línea por línea (y la versión GNU se conoce como GAWK). Este es un caso bastante común. Es incluso más común si produce un archivo de texto a partir de una hoja de cálculo o trabaja con otros tipos de archivos de texto. AWK tiene algunas limitaciones importantes, pero también motosierras. Siguen siendo muy útiles. Aunque AWK suena como un pájaro parecido a un pingüino (ver a la derecha), este es un auk. Suena igual, pero escrito de manera diferente. AWK es en realidad un acrónimo de los nombres del autor original.

Si conoce C y las expresiones regulares de broma, puede aprender AWK después de unos 5 minutos. Si solo conoce C, lea acerca de las expresiones regulares y regrese. Cinco minutos después se encontrará con AWK. Si está ejecutando Linux, probablemente ya tenga GAWK instalado y pueda ejecutarlo con el alias awk. Si está ejecutando Windows, es posible que desee considerar la instalación de Cygwin, aunque hay versiones limpias de Windows disponibles. Si solo quieres jugar en un navegador, prueba webawk.

Bucle de procesamiento AWK

Cada programa AWK tiene incorporado un main () invisible. En código cuasi-C se ve así:

int main(int argc, char *argv[]) {
   process(BEGIN);
   for (i=1;i<argc;i++) {
      FILENAME=argv[i];
      for each line in FILENAME {
         process(line);
      }
   }
   process(END);
}

En otras palabras, AWK lee cada archivo en su línea de comando y procesa cada línea que lee de ellos. Una línea es un conjunto de caracteres que terminan con cualquier cosa en el RS variable (normalmente nueva línea; RS= Separador de registros). Antes de que comience y después de que termine, procesa para BEGIN y END (no exactamente líneas como verá después de un segundo).

Procesamiento de línea

Gran cosa, ¿no? El truco está en el procesamiento de una línea. Esto es lo que hace AWK:

  • Pone toda la línea en una variable especial llamada $0
  • Divide la línea en campos $1, $2, $3etc.
  • Variable FS define la expresión regular para dividir. El valor predeterminado es cualquier espacio en blanco, pero puede establecerlo como comas, comas y espacios, o incluso líneas en blanco.
  • Variable NF obtiene el número de campos en la línea actual.
  • El número de línea para este archivo está en FNR y el número de línea en total está en NR.
  • Ahora el script AWK se ocupa del procesamiento. Los comentarios comienzan con # personaje, así que ignórelos. Van hasta el final de la línea. Todo en la columna 1 (excepto el corchete) es igual. Piense en ello como una subestimación. Si la expresión es verdadera, se ejecuta el código asociado a ella. La BEGIN expresión es verdadera cuando el procesamiento aún no ha comenzado y END es para el procesamiento después de que todo haya terminado. Si no hay condición, el código siempre se cumple.
    Ejemplo:

BEGIN { # brace has to be on this line!
   count=0
}
    { 
    count++
    }
END {
    print count “ “ NR
    }

Puede poner punto y coma como en C si eso lo hace sentir mejor. También puede utilizar un paréntesis (como print(…)). ¿Qué significa el ejemplo? Bueno, en el set inicial count=0 (las variables consisten en según su necesidad y comienzan vacías, lo que significa que realmente no necesitamos esto, porque una variable vacía será nula si se usa como un número). No hay especies. Todo es una cadena, pero puede ser un número cuando sea necesario.
El corchete del medio coincide con cada línea, pase lo que pase. Aumenta el cálculo en 1. Luego, finalmente imprimimos la variable numérica y NR que debe coincidir. Cuando escribe dos cadenas (o variables de cadena) una al lado de la otra en AWK, se convierten en una sola cadena. Entonces eso solo imprime una cuerda count, espacio y NR.

Algo practico

Aquí hay algo más interesante:

BEGIN { # brace has to be on this line!
  count=0
  }
count==10 {
   print “The first word on line 10 is “ $1
}

Esto imprime la primera palabra ($1) desde la décima línea de entrada. Si no da argumentos para imprimir, imprime $0, Paréntesis. En general, esto todavía no es demasiado emocionante. Podría ser más emocionante de usar $1==”Title:” o algo así como una condición. Pero el verdadero poder es que puede usar expresiones regulares como condición. Por ejemplo:

/[tT]itle:/ {

Esta línea coincide con cualquier línea de entrada que tenga un título: o Título: en ella.

/^[ t]*[tT]itle:/ {

Esto sería lo mismo pero solo al comienzo de una línea con 0 o más espacios al frente.
También puede hacer coincidir campos:

$2 ~ /[mM]icrosoft/ # match Microsoft
$2 !~ /Linux[0-9]/ # must NOT match Linux0 Linux1 Linux2 etc.

Funciones

AWK también tiene funciones para expresiones regulares en el código como sub, match, y gsub (ver el manual). También puede definir sus propias funciones. Hacer:

/dog/ {
   gsub(/dog/,”cat”) # works on $0 by default
   print # print $0 by default
   next
}
{
   print
}

Esto transforma las líneas que contienen un perro, para leer un gato (incluso transformar un dogma en un catma). La siguiente palabra clave hace que AWK deje de procesar la línea y vaya a la siguiente línea del archivo de entrada. Puede acortar este script omitiendo tanto la primera impresión como la siguiente. Entonces la última impresión hará toda la impresión.

Conjuntos de asociación

La otra cosa muy útil de AWK es que tiene una base de datos oculta como una matriz. Se trata de matrices asociativas y se asemejan a matrices C con índices en cadena. Aquí hay una secuencia de comandos para calcular el tiempo que aparece una palabra en un texto:

  {
  for (i=1;i<=NF;i++) {
    gsub(/[-,.;:[email protected]#$%^&*()+=]/,"",$i) # get rid of most punctuation
    word[$i]=word[$i]+1
     }
   }

END {
   for (w in word) {
     print w "-" word[w]
    }
}

No olvides que también puedes usar números. foo[4] también hay una matriz. Sin embargo, también puede mezclar y combinar aunque probablemente no debería hacerlo. Es decir foo[4]=10 y foo[“Hello”]=9 ambos son legales y ahora la matriz tiene dos elementos, 4 y “Hello”!

Otra nota: $i y i ¡hay dos cosas diferentes! En la primera pasada del bucle for anterior, i es igual a 1 y $i es el contenido del primer campo (porque i es 1). A menudo ves $NF utilizado, por ejemplo. Este no es el número de campos. Es el contenido del último campo. NF es el número de campos.
Puede ejecutar este script de la siguiente manera:

awk –f word.awk

O, si está en un sistema Unix, puede ejecutar el archivo con "#! / Bin / awk –f" y hacerlo ejecutable.

Uso pirateado

Hay muchas otras cosas que puede hacer con AWK. Puede leer líneas de archivo, leer variables de línea de comando, usar programas de shell para filtrar entradas y salidas, cambiar formatos de salida y más. La mayoría de las funciones de C funcionarán (incluso printf). Puede leer el manual completo en línea y encontrará ejemplos en todas partes.

Quizás se pregunte por qué los piratas informáticos necesitan AWK. La próxima vez, le mostraré algunos usos prácticos que van desde el procesamiento de datos grabados, la lectura de archivos hexadecimales de Intel e incluso la compilación de idiomas. Mientras tanto, es posible que desee utilizar crucigramas para aprender expresiones regulares.

Autor de la foto: [Michael Haferkamp] CC BY-SA 3.0

  • taylorian71 dice:

    Leí el título y pensé que se trataba de recopilar pornografía famosa (¿los luchadores son celebridades?) De archivos de texto ...

  • Sheldon dice:

    Utilizo una combinación de (g) awk / but / (e) grep en la línea de comandos para las cosas rápidas en las que quiero trabajar o, si es algo más serio, simplemente lo escribo en Perl (que tiene edificios muy similares a esas tres herramientas). Al procesar archivos de texto, son herramientas muy útiles para tener cerca (ya sea directamente en * nix o mediante Cygwin).

    Los he usado muchas veces para extraer automáticamente listas de señales de archivos de base de datos internos y, con algo de cuidado, incluso puedo generar los bits útiles para archivos de encabezado (declaraciones de puerto en Verilog / VHDL o SDC / UCF / XDC).

    • Tío fester dice:

      ¡Así es! Perl. Fin de la historia. Los comandos de ala incrustados reclamados en realidad pagan un tiempo de carga mucho más que perl. Perl tiene muchos indicadores de línea de comando para automatizar casos comunes, como hacer un bucle línea tras línea, dividir cada línea en los delimitadores en un conjunto e imprimir los resultados sin siquiera escribir código. Nadie debería usar awk.

      • Pabluski dice:

        Depende de lo que hagas. No todos los sistemas * NIX tendrán PERL, pero ciertamente tendrán Awk. Si está escribiendo algunos scripts que deberían funcionar con todo tipo de sistemas, Awk es una buena herramienta. Utilizo muchas herramientas diferentes dependiendo del trabajo involucrado: Awk, grep, BASH, Javascript, Perl, Python, pero,

  • sonofthunderboanerges dice:

    Utilizo muchas herramientas de MS para analizar archivos de texto enormes para ordenarlos y estandarizarlos para la minería de datos. Utilizo DOS para buscar, reemplazar, etc. MS Excel y MS Word. En un entorno de navegador, puede utilizar expresiones regulares de JSCRIPT también para navegar por el texto. Todavía me gusta crear archivos por lotes de MS DOS para atacar también datos de texto. Encontré una manera fácil de hacer un comando de mensajes de texto en DOS que no sabía que estaba allí. Y no tan complicado COPY CON: [data] [F6] [enter] orden tampoco. Lo uso para el trabajo para escribir una fecha en mi copia por lotes de las fotos de campo de mi cámara en mi disco duro.

    • abad dice:

      "Encontré una manera fácil de ejecutar un comando basado en texto en DOS que no sabía que estaba allí".

      Bueno, hagas lo que hagas, no lo compartas con nosotros ...

    • algún chico dice:

      > Todavía me gusta crear archivos por lotes de MS DOS para atacar también datos de texto.
      Debes estar enfermo. En serio, debes visitar a un médico.

      ¡DOS Batch es algo terrible!

      • sonofthunderboanerges dice:

        Tienes razón, pero me gustan las soluciones rápidas y sucias ...

        • algún chico dice:

          Podemos estar de acuerdo en que está sucio y sí, si realmente lo sabes, incluso podría ser rápido. Personalmente, uso Perl para procesamiento de texto y scripts, a menudo mezclado con comandos de DOS. Para uso personal (y especialmente solo una vez ejecutados los scripts) es mejor y más rápido que buscar cómo usar el práctico módulo de Perl ...
          Por ejemplo, cuando necesito procesar una lista de archivos en un directorio, a menudo uso algo similar
          para mi $ archivo (split (/ n /, `dir / b [/s] * .file`))
          {…. }

          • sonofthunderboanerges dice:

            cualquier chico - supongo que te habrás dado cuenta, como muchos otros HaDers, soy el chico "retro". Es un poco difícil cambiar las viejas formas retro. A veces son útiles. Cuando entré en TI a finales de la década de 2000, solía conocer PERL. También lo usé para la búsqueda / análisis de texto. Sé que hay sistemas que están hechos para manejar archivos de texto enormes y rápidamente. Solo dejé todo sin cultivar cuando cambié de ocupación a lo que hago ahora. Obviamente, no es un trabajo de TI (lo que desearía que fuera, me encantó). Ahora soy demasiado "retro" y los niños y niñas más jóvenes tienen el manillar ahora. Todavía disfruto de la codificación como pasatiempo e invención general. Estoy empezando a pensar en algunas cosas en las que estaba sentado en la-tecnologia.io. Sé que no son de alta tecnología ni están preparados para Arduino, pero me gusta hacer una lluvia de ideas. También podría compartirlo ahora que más tarde cuando no usted puede ...

          • algún chico dice:

            @sonofthunderboanerges
            Absolutamente no te critiqué, al contrario, ¡te molesta por entender DOS batch! Si bien le ayuda a hacer el trabajo, casi todas las herramientas son adecuadas. Y estos conjuntos tienen incluso una ventaja sobre Perl, etc.: no es necesario instalar nada.

  • Dan # 1438459043 dice:

    Gracias a, puede encontrar más buenos ejemplos y aquí, https://rosettacode.org/wiki/Category:AWK

    Este sitio es un gran recurso para la introducción de casi cualquier idioma.

  • Chris dice:

    (g) awk estaba en el cajón superior de mi caja de herramientas, por así decirlo, durante mis años de escuela secundaria. Tenía un script particularmente útil (que todavía uso de vez en cuando) llamado mmmss.awk, que calculaba la desviación mínima, máxima, media, normanda y el tamaño de muestra de un flujo de entrada de números (con una opción para seleccionar diferentes columnas en la entrada). Lo ejecuté todo el tiempo para obtener una sugerencia rápida sobre los datos y asegurarme de que todo va bien antes de comenzar cualquier análisis real. También docenas de otros scripts útiles.

    No sé si esto tendrá sentido para todos, pero siempre he considerado a awk como el equivalente de procesamiento de texto de los PLC (piense en la lógica de escalera).

  • drenehtsral dice:

    Excelente para limpiar copias duplicadas de hojas de datos de chips y transformarlas en símbolos esquemáticos para elegir un formato para su paquete de captura esquemática ...

  • Kjeld Jensen dice:

    Ahemn ... una motosierra es bastante versátil 🙂 Mira este video sobre cómo abrir una botella: https://www.youtube.com/watch?v=yGAZLZ5h_e4 y este (01:37) muestra cómo abrir alrededor de 100 botellas http://www.dr.dk/event/allemod1/video-ole-aabner-sodavand-med-en-motorsav-der-er-damer-i-det#!/

  • Krux dice:

    El procesamiento de textos Unix es un libro excelente y fue lanzado por O'Reilly con su proyecto de libro abierto.

    http://www.oreilly.com/openbook/utp

  • Astro Jetson dice:

    Este código es incorrecto

    BEGIN {# ¡el corchete debe estar en esta línea!
    calcular = 0
    }
    calcular == 10 {
    imprimir "La primera palabra en la línea 10 es" $ 1
    }

    el cálculo no se incrementa

    También puede usar FNR para llamarlo cómo registrarse como en

    FNR == 10 {print "La primera palabra en la línea 10 es" $ 1
    }

América Aguilar
América Aguilar

Deja una respuesta

Tu dirección de correo electrónico no será publicada.