103.2 - Procesar secuencias de texto usando filtros

Importancia

2

Descripción

El candidato debe saber aplicar filtros a secuencias de texto.

Áreas de conocimiento clave:

  • Enviar archivos de texto y flujos de salida a través de filtros de utilidades de texto para modificar la salida usando comandos UNIX estándar incluidos en el paquete GNU textutils.

Contenidos

Outputs y pipes

Una forma importante de hacer que los programas funcionen juntos es a través de piping y redirections. Casi todos sus programas de manipulación de texto obtendrán texto de una entrada estándar (stdin), lo enviarán a una salida estándar (stdout) y enviarán eventuales errores a una salida de error estándar (stderr).

  • A menos que especifique lo contrario, la entrada estándar será la que escriba en su teclado (el programa lo leerá después de presionar la tecla Enter).

  • Los canales de comunicación también son accesibles a través de los dispositivos especiales /dev/stdin, /dev/stdout y /dev/stderr.

En el diagrama se ven el nombre de los canales y el número de referencia. Por cada entrada se producen dos salidas, el output normal y el de error.

En la terminal, teclea cat y luego presiona la tecla Enter. Luego teclea un texto al azar.

Un error común es pensar que cat sirve para "leer" archivos, si vamos a la entrada del manual veremos que no es así (el término proviene de “concatenate”), este en realidad nos sirve para concatenar palabras, lo veremos más adelante.

Como se demostró anteriormente, si no especifica de dónde se debe leer cat, leerá desde la entrada estándar (lo que escribimos stdin) y enviará lo que lea a su ventana de terminal (su salida estándar stdout). Ahora intenta lo siguiente:

El > (mayor que) indica a cat que dirija su salida al archivo mytextfile, no a la salida estándar (stdout). Ahora intenta esto:

Estolo que hace es copiar mytextfile a mynewtextfile. En realidad, puede verificar que estos dos archivos tengan el mismo contenido realizando un diff:

Como no hay salida, los archivos son iguales. Ahora intente con el operador de redireccionamiento anexado (>>):

Hasta ahora hemos usado redirecciones para crear y manipular archivos. También podemos usar tuberías (representadas por el símbolo |) para redirigir la salida de un programa a otro. Encontremos las líneas donde se encuentra la palabra “this”:

Ahora hemos canalizado la salida de cat a otro comando: grep. Nota que cuando ignoramos mayúsculas y minúsculas (usando la opción -i) obtenemos una línea extra como resultado.

A continuación tenemos otro ejemplo más complejo de como funciona:

Este comando:

  • Busca en el directorio raiz / de tipo archivo "type file" que coincidan con el nombre "fstab".

  • El output 1 (stdout) se guardara en un archivo llamado "match.txt".

  • El otuput 2 (stderr) se enviará al "agujero negro" de linux, o sea, no mostrará los errores, se podrían enviar a otro archivo también.

De la misma forma se podría añadir más información al archivo simplemente:

Esto sobrescribirá el archivo con la nueva información.

También podemos realizar la versión inversa, pasarle un archivo como input a un comando a través del símbolo de menor que:

Este comando pasará un contenido de un archivo al comando de acceso a la base de datos mysql.

Hasta ahora hemos usado redirecciones para crear y manipular archivos. También podemos usar tuberías (o pipelines en inglés, representadas por el símbolo |) para redirigir la salida de un programa a otro:

Esto lo que hace es ordenar todas las líneas (frutas) alfabéticamente y seleccionar aquellas que coincida las dos vocales.

Diagrama de flujo

Ver un archivo paginado

Ya hemos visto como cat puede leer la información de un archivo pero en archivos muy grandes no es recomendable usarlo, para ello tenemos utilidades como less:

Esta utilidad es una simplificación de vi (que veremos mas adelante) ya que genera su propia shell child y que nos permite movernos por el archivo con las teclas o buscar palabras con /nombre, para salir escribe q.

La otra utilidad es more que muestra todo el contenido de un fichero en una sola pantalla, pagina el contenido pero solo permite ir hacia delante o atrás.

Otra forma de leer los archivos es formateándolos al ancho deseado lo cual nos puede servir para establecer matrices por ejemplo. fmt lee la salida del fichero ajustado a un ancho determinado:

Recuerda que, tal y como hemos mencionado anteriormente, los espacios también son símbolos y cuentan.


Ordenar archivos

El comando sort ayuda a organizar líneas de texto ordenándolas de distintas maneras, ya sea que trabajes con listas, tablas o archivos de registro, este comando le permite organizar datos según orden alfabético, valores numéricos, columnas específicas o incluso criterios personalizados. En este resumen, exploraremos cómo usar sort de manera efectiva, destacando las opciones más comunes y brindando ejemplos prácticos.

Opciones de comando sort comunes

A continuación, se muestra un resumen rápido de las opciones más comunes del comando sort para realizar diferentes tipos de clasificación:

  • -n : ordena numéricamente, lo que lo hace ideal para listas de números.

  • -r : ordena en orden inverso, mostrando los resultados del más grande al más pequeño (o en orden alfabético inverso para el texto).

  • -k : ordena según un campo o columna específicos, útil para datos estructurados como archivos CSV.

  • -u : elimina líneas duplicadas en la salida ordenada, lo que garantiza resultados únicos.

  • -f : ignora mayúsculas y minúsculas al ordenar, tratando las letras mayúsculas y minúsculas como equivalentes.

  • -o : Dirige la salida ordenada a un archivo en lugar de a la terminal.

  • -t : le permite especificar un delimitador personalizado, como comas en archivos CSV, para la clasificación basada en campos.

Ejemplos prácticos del uso sort

Veamos algunas operaciones comunes que puedes realizar usando el comando sort :

1. Ordenar el texto alfabéticamente

El comportamiento predeterminado de sort es ordenar las líneas alfabéticamente. A continuación, se muestra un ejemplo:

Este comando mostrará el contenido del file.txt en orden alfabético.

2. Ordenar números

Si desea ordenar números en lugar de texto, deberá usar la opción -n . Ordenar valores numéricos es diferente a ordenar texto porque considera la magnitud del número:

Esto ordenará el archivo numbers.txt según el valor numérico de cada línea.

Sin esta opción, los números se ordenarían como texto, lo que podría no dar el resultado deseado (por ejemplo, tratar "10" como menor que "2"). Este comando ordena según el valor numérico de cada línea.

3. Ordenación inversa

A veces, es posible que desee ver los datos ordenados en orden inverso. Simplemente agregue la opción -r para invertir el orden:

Esto se aplica tanto al texto como a los números, dependiendo de sus datos.

4. Ordenar por un campo o columna específicos

Al trabajar con datos estructurados como CSV o archivos separados por tabulaciones, puede ordenar en función de un campo en particular utilizando la opción -k . Por ejemplo, para ordenar por la segunda columna:

Para los archivos CSV donde las columnas están separadas por comas, combine -k con la opción -t para especificar el delimitador (por ejemplo, una coma para archivos CSV):

Este comando ordena el archivo CSV según los valores de la segunda columna.

5. Eliminar duplicados durante la clasificación

Si sus datos contienen líneas duplicadas, puede eliminarlas mientras ordena agregando la opción -u :

Esto le proporciona datos ordenados con solo líneas únicas.

6. Ordenación sin distinción entre mayúsculas y minúsculas

Si desea realizar una ordenación que no distinga entre mayúsculas y minúsculas (por ejemplo, para tratar "Apple" y "apple" como lo mismo), utilice la opción -f :

7. Guardar la salida ordenada en un archivo

También puede guardar la salida ordenada directamente en otro archivo usando la opción -o :

Este comando ordena el contenido de file.txt y escribe el resultado ordenado en sorted_output.txt .


Obtener una parte de un archivo de texto

Si solo necesitamos revisar el inicio o el final de un archivo, hay otros métodos como el comando head se usa para leer las primeras diez líneas de un archivo de manera predeterminada, y el comando tail se usa para leer las últimas diez líneas de un archivo de manera predeterminada. Ahora intente:

Ejemplo para practicar

Archivo datos.csv de ejemplo:


➜ Ordenar por la columna Edad (números):

  • -t, → Indica que el delimitador es la coma.

  • -k3 → Ordena por la tercera columna (Edad).

  • -n → Orden numérico.

➜ Ordenar alfabéticamente por País:

➜ Filtrar personas de México:

➜ Filtrar las filas que contienen "30" (Edad):

  • Uso de ,30, para evitar confundir con otro número como 130.

➜ Contar el número de filas en el archivo:

  • Muestra cuántas líneas tiene el CSV.

➜ Contar el número total de palabras:

➜ Numerar todas las filas:

➜ Numerar desde la fila 2 (omitiendo la cabecera):

➜ Mostrar las primeras 3 filas:

➜ Mostrar las últimas 3 filas:


➜ Filtrar las personas de México, ordenarlas por edad y numerarlas:


Modificación de textos

uniq elimina las líneas adyacentes consecutivas por lo que muchas veces se usa con sort para eliminar líneas repetidas. Usando de ejemplo un listado de frutas con líneas repetidas debería devolvernos un listado de las frutas en general con el siguiente:

Este comando realiza lo mismo que sort -u

tr traduce caracteres en el sentido que reemplaza y modifica la salida pero no el archivo. Se puede usar para cosas como poner las mayúsculas en minúsculas o traducir los espacios por comas, etc. Se trata de un comando muy útil en el tratamiento de textos.

Vamos a ver algunos ejemplos:

paste mezcla línea a línea dos archivos y el resultado lo muestra tabulado. Por ejemplo, si creamos un fichero de animales y lo juntamos con el de frutas el resultado será:

Resultado

expand es otro comando útil para cambiar tabulaciones por espacios. Al usarlo con el anterior el resultado es el siguiente:

Donde -t se usa para especificar el número de espacios.

Resultado

cut es la herramienta principal para recortar caracteres o mostrar los campos que tu le pidas según un patrón establecido (, o - o una repetición de letras por ejemplo):

Quizás una de las funciones más interesantes es el delimitador:

El csv es el siguiente:

clients.csv

Al aplicar el comando, el resultado es el siguiente:

Resultado

split es una utilidad que separa un archivo en paquetes lo cual puede ser útil para separar un archivo muy grande. El parámetro -b establece el tamaño máximo de los paquetes:

Ejemplo con split

Para practicar más comandos podemos trabajar con split, primero dividiremos un archivo en muchos paquetes (procura no pasarte):

En este ejemplo dividimos el archivo en paquetes de 20 Bytes

Vamos ahora a contar cuantos archivos ha creado:

Podriamos volver a leer el archivo completo usando la wildcard con cat:

Fíjate que split genera un montón de archivos llamados x— si queremos borrarlos podemos usar otra vez la wildcard:

El último comando es el yes que sirve para repetir una palabra infinitamente:

(Imprimirá "hola" en cada línea hasta que lo interrumpas con Ctrl + C).

También podemos:

  • Confirmar automáticamente una pregunta en un script:

    (Simula que el usuario escribe "y" repetidamente, confirmando la eliminación).

  • Generar un número limitado de líneas:

    (Genera exactamente 10 líneas con la palabra "ifp").

Caso práctico: Listado de correos

A partir del siguiente csv, vamos a generar un listado de correos usando los comandos aprendidos hasta ahora:

Queremos construir una lista que funcione como <nombre>@ifp<empleo>.com

Para ello vamos a construir una sentencia con "pastes"

Ahora construimos el comando teniendo en cuenta que paste admite dos parametros:

Ahora lo interesante seria hacer lo mismo pero con inicial.apellido:


Garantizar la integridad de los datos

Como ves, es muy fácil manipular archivos en Linux y eso puede ser un problema, por ejemplo, es posible que deseemos compartir un archivo con otra persona y queremos asegurar que el destinatario termina con una copia verdadera del archivo original. Un uso muy común de esta técnica se practica cuando los servidores de distribución de Linux alojan imágenes de CD o DVD descargables de su software junto con archivos que contienen los valores de suma de comprobación calculados de esas imágenes de disco.

Una suma de comprobación es un valor derivado de un cálculo matemático, basado en una función hash criptográfica, contra un archivo. Existen diferentes tipos de funciones hash criptográficas que varían en intensidad. El examen espera que estés familiarizado con el uso de md5sum, sha256sum y sha512sum.

Pongamos el caso de apache2, si vamos a la web de descarga veremos lo siguiente:

En amarillo está marcado la verificación

El SHA256 del archivo lo obtenemos de la web directamente:

Ahora descargamos el archivo en nuestro SO:

Vamos ahora con la comprobación:

Si tratáramos de alterar el archivo y volver a hacer la misma secuencia, este último comando fallaría.

También, por practicar, podríamos realizar el procedimiento de comprobación con el comando diff que comparará archivos línea por línea:

  • cut -d " " -f 1: Recorta solo el hash sin el nombre del archivo.

  • diff <(): Se le pasa los hashes a diff.

Podriamos realizar esta misma sentencia con vimdiff para revisar los cambios caracter por caracter.

Lo mismo funciona con md5sum y sha512sum con sus respectivos hashes.

Buscando más en los archivos

El comando octal dump (od) a menudo se usa para depurar scripts, aplicaciones y varios archivos. Hay varias opciones para el od, como la opción -A para controlar el radix de los desplazamientos de archivo o -t para controlar la forma del contenido del archivo presentado.

El radix puede ser especificado como o, (octal, el predeterminado), d (decimal), x (hexadecimal), o n (sin desplazamientos mostrados). Puedes mostrar el resultado como octal, hex, decimal, punto flotante, ASCII con escapes de barra inversa, o caracteres con nombre (nl para newline (\n), ht para horizontal tab, etc.).

Vamos a probar:

Resultado en octal

La primera columna de salida es el desplazamiento de bytes para cada línea de salida. Como od imprime la información en formato octal de manera predeterminada, cada línea comienza con el desplazamiento de bytes de ocho bits, seguido de ocho columnas, cada una con el valor octal de los datos dentro de esa columna.

Para ver el contenido de un archivo en formato hexadecimal, usamos:

Resultado en hexadecimal

Para verlo en formato carácteres, mas leible usamos:

Como ves, la diferencia se produce en aquellos caracteres especiales como el salto de línea en este caso.

Para omitir el desplazamiento de bytes:

Donde:

  • -A n: No muestra las direcciones de memoria (evita la numeración de las líneas).

  • -c: Muestra los caracteres imprimibles y representa los no imprimibles con secuencias especiales (ej. para nueva línea, para tabulación).


Leer un archivo comprimido

Crearemos un archivo llamado ftu.txt que contenga una lista de los siguientes comandos:

Ahora usaremos el comando grep para imprimir todas las líneas que contienen la cadena cat:

En el siguiente topic veremos las diferencias y el funcionamiento de los archivos comprimidos, mientras te basta saber que estos sirven para concatenar o leer:

  • bzcat para archivos comprimidos bzip

  • xzcat para archivos comprimidos xz

  • zcat para archivos comprimidos gzip

Ahora vamos a ver como leer los archivos:


Los fundamentos de sed, el Editor de Stream

La mayor parte de lo que podemos hacer con grep también podemos hacerlo con sed, el editor de flujo para filtrar y transformar texto, para ello, primero recuperaremos nuestro archivo ftu.txt descomprimiendo nuestro archivo gzip del archivo:

Dónde:

  • El signo menor que < dirige el contenido del archivo ftu.txt a al comando sed.

  • La palabra encerrada entre barras (es decir, /cat/) es el término que estamos buscando.

    • /cat/: Especifica un patrón de búsqueda. En este caso, cat es el patrón que sed está buscando en el archivo. sed busca todas las líneas que contienen el texto "cat".

    • p: Es el comando de impresión (print). Cuando sed encuentra una línea que coincide con el patrón cat, el comando p le indica a sed que imprima esa línea.

  • La opción -n instruye a sed para que no imprima automáticamente cada línea del archivo a medida que es procesada. En otras palabras, silencia la salida por defecto.

De la misma forma que hacíamos con grep -v podemos realizar la búsqueda inversa con:

Si no usamos la opción -n, sed imprimirá todo desde el archivo, excepto lo que la d indica a sed que elimine de su salida.

Un uso común de sed es buscar y reemplazar texto dentro de un archivo. Suponga que desea cambiar cada aparición de cat a dog. Puedes usar sed para hacer esto proporcionando la opción s para intercambiar cada instancia del primer término, cat, por el segundo término,

Ahora, en lugar de utilizar < para pasar el archivo ftu.txt, podemos hacer que el comando opere directamente en el archivo. Por ejemplo, creamos simultáneamente una copia de seguridad del archivo original y operamos sobre el otro:

La opción -i realiza una operación sed directamente en el archivo original, si no pusiéramos el .backup después del parámetro -i, simplemente sobrescribiría su archivo original.

Algunos ejemplos más con sed:

  • Para mostrar los usuarios del sistema y su shell de inicio de sesión predeterminado, escribirás:

El comando de sustitución le indicará a sed que reemplace cualquier texto entre el primer y el último colon (:) de cada línea por un solo colon (:), eliminando efectivamente cualquier contenido entre los dos puntos del archivo original. El archivo original permanece sin cambios y la salida se envía a la salida estándar (la terminal).

  • Para listar los últimos usuarios que iniciaron sesión, excepto root, escribirás:

Un uso muy común de sed es formar parte de una tubería. Aquí se usa para filtrar (utilizando el comando (d)elete ) todas las líneas que comienzan con la palabra root (^ significa el inicio de la línea).

Más info: https://quickref.me/sed.html

Caso Práctico: Análisis de Logs del Servidor Web

Vamos a ver un caso práctico en el que revisaremos varias cosas de un log de nginx, un servicio web, si ya tienes un servidor con nginx que se ha usado puedes obtener los Datos así:

Cada línea en logs.txt tiene este formato:

Si no tienes nginx instalado, te dejo un log de ejemplo a continuación para que lo crees tu mismo en tu sistema:


A continuación vamos a realizar una serie de acciones:

1. Verificar el Tráfico de un Usuario Específico

Para ver todas las solicitudes de la IP 192.168.1.12:

Para buscar todas las respuestas 404:


2. Identificar las IPs con Más Accesos

🔹 Explicación:

  • cut -d' ' -f1 → Extrae la primera columna (la IP).

  • sort → Ordena las IPs.

  • uniq -c → Cuenta repeticiones.

  • sort -nr → Ordena de mayor a menor.

  • head -10 → Muestra las 10 IPs más frecuentes.

📌 Salida esperada:


3. Filtrar Errores HTTP 4xx y 5xx

🔹 Explicación:

  • grep 'HTTP/1.1" 4[0-9][0-9] ' → Busca códigos 4xx.

  • grep 'HTTP/1.1" 5[0-9][0-9] ' → Busca códigos 5xx.

📌 Salida esperada (errores 4xx y 5xx):


4. Extraer las URLs Más Visitadas

🔹 Explicación:

  • cut -d'"' -f2 → Toma el contenido entre comillas (GET /index.html HTTP/1.1).

  • cut -d' ' -f2 → Extrae solo la segunda palabra (la URL).

  • sort | uniq -c | sort -nr | head -10 → Cuenta y ordena.

📌 Salida esperada:


Last updated