Viernes, Mayo 24, 2019

Filtros: awk, grep, sed y cut

filtros

Conforme vas avanzando en los capítulos de este tutorial sobre el terminal, ya estás viendo que esto se está complicando. Sin embargo, que se esté complicando, implica a su vez que le vas a poder sacar mucho mas partido al terminal. Precisamente, este capítulo puede ser el que a priori, le veas menos partido, pero, justo es todo lo contrario. El objetivo de este capítulo es trabajar con archivos de texto, gestionar su contenido, buscar en su interior. Es decir, el objetivo no es mas ni menos que filtrar texto. Para ello, te voy a comentar cuatro herramientas, awk, grep, sed y cut. Estas son algunas de las opciones para filtrar archivos de texto, pero hay muchas mas.

Recuerda que en el capítulo 3 sobre gestionar archivos, te comenté que, en Linux todo es un archivo, con lo que ya estás viendo un poco el potencial de esto. Pero si además, recuerdas que en el capítulo anterior, te comenté la posibilidad de encadenar la ejecución de herramientas, es decir, encadenar la salida de una, a la entrada de otra… el potencial es realmente espectacular.

Y ahora, que ya sabes el potencial que puedes llegar a tener entre tus dedos, ya te estás preguntando, ¿que herramientas necesito?¿como puedo acumular todo ese poder entre mis dedos?.

Filtros: awk, grep, sed y cut

La información está guardada en archivos de texto. Ya sean los archivos de registro o Log, ya sea los archivos de configuración, etc. Pero estos son solo unos pocos, mas si trabajas con archivos de texto plano, como markdown o org-mode. Cualquier cosa que quieras encontrar, es posible encontrarla en segundos, utilizando alguna de las herramientas que vas a ver en este capítulo.

Es mas, hoy en día que no te preocupas por el espacio ocupado, ya que el precio del GB es relativamente muy barato, te has acostumbrado a guardar todo, por si acaso. Tenemos un profundo síndrome de diógenes digital.

Las herramientas que verás en este capítulo para filtrar texto, servirán para paliar este problema.A continuación te mostraré estas herramientas para filtrar texto, y que pronto aprenderás a amar.

Para ver las posibilidades que nos ofrecen estas herramientas he descargado la primera parte de Don Quijote de la Mancha, en texto plano. Tu también la puedes descargar de GitHub, para probar por ti mismo estas herramientas.

awk

awk busca en archivos en busca de texto que cumpla con un determinado patrón. De esta manera, cuando una línea cumple con ese patrón, awk realizará una acción en esa línea concreta. Así, entre los parámetros que le vamos a pasar a awk, también se encuentra, esa acción.

¿Que acciones puedes pasar para que realice awk? Todas las que puedas imaginar. Y es que awk es un lenguaje de programación, con lo que ya te puedes hacer una idea de las posibilidades que tienes. Sin embargo, no es el objeto de este tutorial, entrar en detalle, en todas las posibilidades que te da awk, como aplicación o como lenguaje. Simplemente se trata de que veas la punta del iceberg del mismo, y en su caso que te adentres en awk si lo consideras necesario o te puede ser de utilidad para el desempeño de tu trabajo. En este artículo solo vas a ver algunas funciones de awk, que te permitirán filtrar texto en Linux, de una manera relativamente sencilla.

Uso básico de awk

El uso de awk es tan sencillo como awk '[intrucciones]' [archivo]. Dentro de las instrucciones le podemos indicar una condición para que en función de esa condición realice una acción.

Funciones de awk

Dentro de las funciones que permite awk te indico solo las que considero mas interesante para el filtrado de archivos. Próximamente escribiré un artículo entrando mas a fondo con el uso de esta herramienta y lenguaje, por que ciertamente se lo merece.

  • length. Para determinar la longitud de un texto
  • index. Indica la posición de una cadena de texto dentro de otra.
  • substr. Extrae una parte de una cadena.
  • tolower. Convierte a minúsculas.
  • toupper. Convierte a mayúsculas.
  • printf. Imprime el contenido.
  • print. Igual que el anterior, pero añade un salto de línea.
  • sprintf. Devuelve una cadena de texto formateada en función de los parámtros indicados.

Como digo estas no son mas que algunas de las funciones que admite awk.

Parámetros de awk

Por otro lado, puedes utilizar algunos parámetros que te facilitarán enormemente el trabajo con awk. Algunos de estos parámetros son los siguientes,

  • $0. Se corresponde con una línea completa.
  • $1, $2, $3,..... Se corresponden con la primera palabra, con la segunda palabra, etc.
  • FS. Es el separador.
  • NF. Es el número de palabras de una línea.

Algunos ejemplos y usos de awk

Si en nuestro ejemplo quieres imprimir todas las líneas, utiliza

awk '{print}' el_quijote.txt

o bien

awk '{print $0}' el_quijote.txt

¿Y si quisieras imprimir solo las que contienen la palabra Sancho? En ese caso, tendrías que ejecutar

awk '/Panza/ {print $0}' el_quijote.txt

Lo que ves entre // es una expresión regular, que ya te he comentado en el capítulo 5 sobre comodines y expresiones regulares. Si quieres imprimir solo aquellas que empiezan con la palabra Sancho, utilizarás como ya sabes,

awk '/^Sancho/ {print $0}' el_quijote.txt

Para que las búsquedas no tengan en cuenta mayúsculas y minúsculas, la cosa se complica ligeramente.

awk 'BEGIN{IGNORECASE=1} /^sancho/ {print $0}' el_quijote.txt
extraer palabras con print

Una características muy interesante de print es que nos permite extraer palabras de cada línea. Por ejemplo si quieres imprimir la primera palabra de cada línea, donde aparezca Quijote, tendrías que ejecutar,

awk '/Quijote/ {print $1}' el_quijote.txt

Un ejemplo práctico. Si listamos ls -lah en el directorio donde hemos creado los archivos indicados, nos devolverá algo similar a,

-rw-rw-r--  1 lorenzo lorenzo   12 mar 15 07:47  ejemplo1.txt
-rw-rw-r--  1 lorenzo lorenzo   12 mar 15 07:47  ejemplo2.txt
-rw-rw-r--  1 lorenzo lorenzo 1,1M ene 26  2017  el_quijote.txt

¿Como imprimir el nombre del archivo seguido del tamaño?

ls -lah | awk '{print $5 "-" $9}'

Esto es así porque considera como delimitador el espacio. Ahora bien, puedes cambiar el delimitador para que en lugar de ser un espacio sea ;. Y aquí es donde ya ves el potencial a la hora de trabajar con hojas de cálculo en formato CSV.

El primer paso es cambiar el delimitador. Para ello, pasaremos como parámetro -F, que nos permite indicar el delimitador. El segundo paso es crear un par de archivos, para poder prácticar con esta nueva opción. Para esto, vamos a ejecutar estas dos órdenes,

echo "1 2 3 4 5 6" > ejemplo1.txt
echo "1;2;3;4;5;6" > ejemplo2.txt

Si quisieras extraer la tercera columna de los archivos que has creado anteriormente, solo tienes que ejecutar,

awk '{print $3}' ejemplo1.txt
awk '{print $3}' ejemplo2.txt

En el caso de ejemplo1.txt te devolverá 3. Sin embargo, en el caso del segundo archivo te devolverá 1;2;3;4;5;6. Sin embargo, si cambiamos el delimitador con la opción -F ';' el resultado será el esperado.

awk -F ';' '{print $3}' ejemplo2.txt

grep

Esta herramienta te permitirá imprimir todas aquellas líneas que coincidan con el patrón que hayas especificado. Pero no solo, esto, sino que puedes buscar todas las líneas de todos los archivos. ¿Ves las posibilidades?.

Imáginate mi caso, donde todos los artículos que puedes leer en este blog, los he escrito en Markdown. ¿Sabes lo que me cuesta buscar en que artículo escribí sobre Touchpad-Indicator? Tan sencillo como ejecutar el siguiente comando,

grep -i -r 'touchpad-indicator' /home/lorenzo/articulos/*

Las opciones que he añadido son,

  • -i para que no distinga entre mayúsculas y minúsculas
  • -r esta opción es para realizar una búsqueda recursiva

También es posible combinar las opciones de forma que quedará como grep -ir.

Pero no solo esto, sino que también podemos contar las veces que aparece una palabra dentro de un archivo. Así, si queremos ver las veces que aparece quijote dentro de nuestro texto, ejecutaremos,

grep -ic 'quijote' el_quijote.txt

Lo que da un total de 590 veces. Si además, quieres ver las líneas donde no aparece, ejecuta,

grep -icv 'quijote' el_quijote.txt

Lo que da un resultado de 1596 veces. La opción -v te permite, buscar todas aquellas líneas donde no se encuentre el patrón indicado.

Si quieres buscar todos los archivos donde está la palabra quijote, y que además las cuente, utiliza,

grep -isrc 'quijote' *

El problema de esta ejecución es que te devuelve todos los archivos, junto con el número de repeticiones. Evidentemente, la mayoría aparecerán como 0. ¿Como quitar esas líneas que no nos dan ninguna información? Encadenando dos ejecuciones de grep, tal y como puedes ver a continuación,

grep -isrc 'quijote' * | grep -v ':0$'

Esto te dará el siguiente resultado,

el_quijote.txt:590

sed

Esta es una de las herramientas que junto con las anteriores, mas potencial tiene a la hora de realizar el filtrado y transformación de archivos de texto. En definitiva, sed es un editor de flujo de texto. Este editor de flujo te permite realizar transformaciones en el flujo de entrada.

Dentro de todas las posibilidades que te ofrece lo mas utilizado es la posibilidad de sustituir texto. Para ello, de nuevo hace uso de las expresiones regulares. Es importante que tengas en cuenta, que lo que hace es modificar el flujo de entrada, pero no el archivo original, es decir, te ofrece un flujo de salida modificado. Si quieres guardar ese flujo de salida modificado deberás hacer uso de los operadores de redirección.

El uso de esta herramienta es el siguiente

sed 'operación' archivo

Algunos ejemplos del uso de sed

Si quieres reemplazar todas las apariciones de panza por barriga en el archivo de ejemplo, utiliza la siguiente orden,

sed 's/panza/barriga/g' el_quijote.txt

Si quieres que esto se haga con independencia de mayúsculas y minúsculas,

sed 's/Panza/Barriga/gi' el_quijote.txt

Así el resultado que obtendrás será algo como,

Sancho Barriga es aquéste, en cuerpo chico
pero grande en valor, ¡milagro extraño!
Escudero el más simple y sin engaño
que tuvo el mundo, os juro y certifico.

Si quieres guardar esta alternativa, utilizando los operadores de redirección,

sed 's/Panza/Barriga/gi' el_quijote.txt > el_quijote_v2.txt

Si quieres reemplazar dos o mas espacios por uno solo,

sed 's/\s+/ /g' el_quijote.txt

En el caso de que quisieras insertar un asterisco al principio de cada línea,

sed 's/^/*/g' el_quijote.txt

cut

Esta herramienta te permite mostrar por la salida estándar, es decir, por pantalla, parte de cada una de las líneas del archivo que le pases. Es decir, le puedes indicar, de cada línea o fila del archivo que es lo que quieres que te muestre. Al igual que otras herramientas, esta también dispone de una serie de opiones que te permite definir que es lo que quieres mostra de cada una de las líneas.

  • -b permite seleccionar un byte o listado de bytes separados por comas. También es posible definir rangos. Para definir rangos tienes que utilizar -. Así para definir del byte 1 al 10, tienes que indicar -b 1-10. Si lo que quieres es del byte 1 al final, -b 1-. Por contra, si lo que quieres es seleccionar hasta el byte 5, utiliza -b -5.
  • -c lo mismo que en el caso anterior pero esta vez para caracteres.
  • -d por defecto cut tiene definido como delimitador el tabulador. Con esta opción, puedes definir otro delimitador distinto.
  • f esta opción te permite seleccionar los campos. Un campo es el elemento situado entre delimitador y delimitador. Si seleccionas mas de un campo, te los devolverá separados con el delimitador que hayas indicado.

Un uso muy interesante de cut es como archivos CSV, me refiero a los archivos separador por comas. Realmente, yo los prefiero utilizar separados por punto y coma, por aquello de los decimales. Así, suponiendo que me haces caso, y los separas por punto y coma, partiendo de este archivo letras.csv, prueba con algunas opciones.

a;b;c;d;e;f;g;h
  • cut -d ';' -f 3 letras.csv -> c
  • cut -d ';' -f 3,5,7 letras.csv -> c;e;g
  • cut -d ';' -f 3- letras.csv -> c;d;e;f;g;h
  • cut -d ';' -f -5 letras.csv -> a;b;c;d;e

Conclusiones

Indicar que cada una de las herramientas que has visto en este capítulo del tutorial, ya se merece un capítulo por si misma. Solo tengo que recordarte que awk es un lenguaje de programación, o sea que imagínate todo lo que se puede hacer. Aquí solo has visto la punta del iceberg.

Sin embargo, este es el uso mas frecuente que yo le doy a estas herramientas, con lo que te puede servir de orientación.

Por último, indicarte que este capítulo de filtros lo he tenido que dividir en dos partes, por la cantidad de herramientas que hay disponibles. En la siguiente parte del tutorial, tendrás a tu disposición un nuevo abanico de herramientas disponibles.

 

Más información:

Fuente: atareao

Compártelo. ¡Gracias!

 
Grupo Digital de Ayuda! Laboratorio Linux! - Linux para todos.

¿Quién está en línea?

Hay 421 invitados y ningún miembro en línea

Contador de Visitas

9736732
Hoy Hoy 612
Ayer Ayer 2123
Esta semana Esta semana 8326
Este mes Este mes 43416
Total de Visitas Total de Visitas 9736732

Día con más
visitantes

05-06-2019 : 2257

Gracias por su visita