AWK y yo
He creado este artículo con AWK. Para ello me han bastado 19 líneas de código. AWK es un lenguaje de programación maravilloso para tratar textos e información que viene en formato texto, que es muchísima.
Mi primera incursión seria en AWK vino de la lectura de «The Awk Programming Language», escrito por Alfred Aho, Peter Weinberger y Brian Kernigham —no sé si lo pilláis— y para sacar partido de él me bastó con la introducción. En serio. Luego, claro, he profundizado un poquito.
AWK es un lenguaje que sirve para muchas cosas pero está pensando para manejar fácilmente grandes cantidades de datos en archivos de datos csv. Por si acaso un csv es un archivo de texto plano en el que los datos están ordenados por líneas y columnas, distinguiéndose las columnas por un carácter separador, normalmente una coma. Algo como esto:
Goblin 7 -1 Daga Humanoide Orco 9 +2 Lanza Humanoide Lobo 6 +1 Dientes Animal …
Lo que sería un bestiario de juego de rol clásico, pero imagina que tiene unas quinientas líneas. Aquí el separador sería el espacio en blanco, que, curiosamente es el mismo que usa AWK.
Pues bien AWK te permite usar esos datos de forma sencilla. Básicamente examina línea por línea, busca lo que quieres de esa línea, le aplica los cálculos u órdenes que le mandes y te los devuelves ordenados y conforme a tus deseos.
Para ello usa símbolos como $0 para el contenido completo de la línea que se está examinando y luego $1, $2, $3… para cada una de las columnas. Así para extraer las todos los humanoides te bastaría comprobar en cada línea si $5 es igual a Humanoide.
De hecho puedes hacer cualquier cosa que podrías hacer con una hoja de cálculo, y no sé si más. Y en cuanto a la flexibilidad de los datos, mira una cosa, el archivo de datos del ejemplo anterior también lo podríamos haber escrito separando los campos en líneas y los registros por una línea en blanco.
Goblin 7 -1 Daga Humanoide Orco 9 +2 Lanza Humanoide Lobo 6 +1 Dientes Animal
Para ello basta con ajustar dos variables
FS o Field separator y RS o Record separator. Para ello basta la orden:
FS = "\n" RS = ""
. FS y RS son nombres reservados de AWK precisamente deben usarse solamente para describir el formato de cómo estarán separados los datos u, obviamente, el resultado será o un error o algo más divertido.
Volvamos al libro.
Lo básico del lenguaje está en el capítulo introductorio y esto es suficiente para la mayoría de las cosas, teniendo al lado la referencia, o una chuletita. En el capítulo segundo tienes una descripción completa del lenguaje y a partir de ahí ejemplos cada vez más avanzados de cómo usar el lenguaje, llegando, incluso a describir cómo crearte tu propio lenguaje de programación para usos específicos usando AWK, para lo que no tengo palabras.
AWK viene casi siempre de serie con Linux, salvo en las distribuciones más específicas. Yo lo estoy usando para extraer las estadísticas en bruto de esta cápsula, extrayendo los errores que encuentran los clientes al acceder a ella, por ejemplo, de un log con miles de entradas. Sí, lo podría hacer con miles de cosas diferentes pero AWK lo hace de forma eficiente y con prácticamente nada que recordar. Vamos, literalmente con una línea de código.
aEntrada.awk
Déjame terminar con mi programita, que viene preparado para usarlo en Linux, pero supongo que debería poder funcionar en todo sistema operativo POSIX, con un poco de suerte en un MAC, aunque no lo he probado.
Va dividido en dos partes. La sección BEGIN
se ejecuta antes de leer los datos. En mi caso solo ajusto unas variables. La segunda, que viene sin nombre, se ejecuta una vez para cada registro y no hay mucho que comentar. Quizás sorpenda que AWK concatene ristras (strings) de texto simplemente escribiéndolas una detrás de otras; pero es así. Los system() son llamadas al sistema operativo, en este caso a una herramienta llamada cat que imprime el contenido de un archivo.
Nota: AWK permite una tercera parte, llamada END que se ejecuta una vez se han tratado todos los registros.
Uso
Si aEntrada.csv es donde tengo los datos de los artículos que quiero generar y ficheroSalida.html donde quiero que acabe publicado, llamaría a:
awk -f aEntrada.awk aEntrada.csv > ficheroSalida.html
Contenido de aEntrada.csv
AWK, un lenguaje de programación sencillo y genial awk.html Otro registro de ejemplo ejemplo.html
La primera línea se convertirá en la variable $1 y la segunda en $2. $1 contiene el título de este artículo, y $2 el nombre de archivo del borrador que he grabado en la carpeta «drafts».
BEGIN { linkb = "https://mluiesp.com/" FS = "\n" RS = "" author = "Miguel de Luis Espinosa" } { system("cat head.html") print "<title>"$1 "-" author "</title>" print "</head>\n\n<body>\n<article>" print "<section>\n<header>" print "<h1>" $1 "</h1>" print "<p class='subtitle'>de <a href='" linkb "index.html'>"author"</a></p>" print "</header>\n</section>" system("cat drafts/" $2 ) print "</article>\n</body>" system("cat footer.html") }
Nota: Este artículo lo escribí para otra página que tenía una estructura y estilo diferente. Ahora estoy usando un sistema que incorpor jinja2 y python, del que seguramente os hablaré.