Saltar a contenido

📚 Módulo 4: Dominando texto y datos

Duración estimada: 3-4 horas según tu ritmo y experiencia.

Objetivo: Procesar y manipular texto con grep, sed y awk, y entender las expresiones regulares básicas para filtrar y transformar datos desde la terminal. 🎯

Prerrequisitos: Haber completado los Módulos 1-3, saber usar scripts básicos, variables, redirecciones y bucles for.

Nota: El procesamiento de texto es una de las habilidades más valiosas en Bash. Practica cada herramienta por separado antes de combinarlas.


📖 Contenidos del Módulo

4.1. Creando y explorando archivos de texto 🌱

Teoría:

Antes de procesar texto necesitamos archivos con los que trabajar. En este módulo usaremos printf para crear contenido multilínea de forma fiable. Aunque echo -e también puede interpretar secuencias de escape como \n para saltos de línea, printf es más portable y predecible entre distintos sistemas, por lo que es la herramienta recomendada para generar ficheros de prueba.

Práctica:

  1. Crea un archivo de texto con varias líneas usando printf:
printf "Hola mundo\nLinux es genial\nBash es poderoso\n" > texto.txt
cat texto.txt

printf interpreta \n como salto de línea y escribe el resultado en texto.txt. Deberías ver tres líneas.

  1. Añade más líneas al archivo:
printf "Aprendiendo Bash\nLa terminal es tu amiga\n" >> texto.txt
cat texto.txt
  1. Muestra el archivo con número de líneas usando cat -n:
cat -n texto.txt

La opción -n añade el número de línea delante de cada una.

  1. Muestra solo las tres primeras líneas con head:
head -n 3 texto.txt
  1. Muestra solo las dos últimas líneas con tail:
tail -n 2 texto.txt

Dato curioso: head y tail son muy útiles para inspeccionar archivos de log sin abrirlos enteros. 😄


4.2. grep: Filtra líneas como un detective 🖌️

Teoría:

grep busca líneas que coincidan con un patrón dentro de un archivo o de la entrada estándar. Opciones esenciales:

  • -i — ignora mayúsculas/minúsculas.
  • -v — muestra las líneas que no coinciden.
  • -n — muestra el número de línea.
  • -r — busca de forma recursiva en directorios.
  • -c — cuenta el número de líneas que coinciden.

Práctica:

  1. Busca líneas que contengan "Bash":
grep "Bash" texto.txt
  1. Busca sin distinguir mayúsculas/minúsculas:
grep -i "bash" texto.txt
  1. Muestra las líneas que no contienen "Bash":
grep -v "Bash" texto.txt
  1. Busca con número de línea:
grep -n "Linux" texto.txt
  1. Cuenta cuántas líneas contienen la palabra "es":
grep -c "es" texto.txt

Consejo: Combina grep con pipes para filtrar la salida de otros comandos: ls -l | grep "^d" lista solo los directorios. 💡


4.3. sed: Edita texto en el flujo ⚙️

Teoría:

sed (stream editor) transforma texto línea a línea sin abrir un editor interactivo. El uso más común es la sustitución: sed 's/patrón/reemplazo/'. Por defecto solo reemplaza la primera ocurrencia de cada línea; añade g al final (s/patrón/reemplazo/g) para reemplazar todas.

Práctica:

  1. Crea un archivo de personas para practicar:
printf "Juan 25\nMaria 30\nPedro 22\n" > personas.txt
cat personas.txt
  1. Sustituye "Juan" por "Carlos":
sed 's/Juan/Carlos/' personas.txt

Observa que el archivo original no cambia; sed muestra el resultado en pantalla.

  1. Guarda el resultado en un nuevo archivo:
sed 's/Juan/Carlos/' personas.txt > personas_nuevo.txt
cat personas_nuevo.txt
  1. Borra las líneas que contienen "Pedro":
sed '/Pedro/d' personas.txt

La opción d elimina las líneas que coinciden con el patrón.

  1. Reemplaza todas las ocurrencias en una línea con la flag g:
echo "uno uno uno" | sed 's/uno/dos/g'

Sin g, solo se reemplazaría el primer "uno".

Advertencia: Para modificar el archivo original directamente usa sed -i 's/patrón/reemplazo/' archivo. Hazlo con cuidado: no hay deshacer. 🛑


4.4. Expresiones regulares básicas 📜

Teoría:

Las expresiones regulares (regex) son patrones que describen conjuntos de cadenas de texto. Metacaracteres esenciales:

  • . — cualquier carácter excepto el salto de línea.
  • * — cero o más repeticiones del elemento anterior.
  • ^ — inicio de línea.
  • $ — fin de línea.
  • [abc] — cualquiera de los caracteres entre corchetes.
  • [^abc] — cualquier carácter excepto los indicados.

grep usa por defecto expresiones regulares básicas (BRE). Para usar la sintaxis extendida (ERE), que incluye +, ?, {n,m} y |, es necesario el flag -E. Sin él, esos metacaracteres se tratan como texto literal.

Práctica:

  1. Busca líneas que empiecen por una letra mayúscula:
grep "^[A-Z]" texto.txt
  1. Busca líneas que terminen con "al":
grep "al$" texto.txt
  1. Usa ERE con -E para buscar una o más vocales seguidas:
grep -E "[aeiou]+" texto.txt

Sin -E, el + se interpretaría como un carácter literal, no como "una o más repeticiones".

  1. Valida el formato de una dirección de correo con ERE:
echo "email@dominio.com" | grep -E "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"

Este patrón requiere -E porque usa + y {2,}, que son sintaxis ERE. Si no añades -E, no obtendrás ninguna coincidencia aunque el email sea válido.

  1. Filtra líneas que contengan exactamente un número de dos dígitos:
grep -E "\b[0-9]{2}\b" personas.txt

Consejo: Empieza con patrones simples y ve añadiendo complejidad poco a poco. RegExr es una herramienta web muy útil para probar expresiones regulares de forma visual. 💡


4.5. awk: Procesa datos estructurados 🚀

Teoría:

awk es un lenguaje de procesamiento de texto orientado a columnas. Por defecto usa el espacio (o tabulación) como separador de campos. Las variables especiales más importantes son:

  • $1, $2, $N — el campo N de la línea actual.
  • $0 — la línea completa.
  • NR — número de línea actual.
  • NF — número de campos en la línea actual.

La estructura básica es: awk 'condición { acción }' archivo

Práctica:

  1. Muestra solo la primera columna (nombres) de personas.txt:
awk '{print $1}' personas.txt
  1. Muestra nombre y edad con un formato personalizado:
awk '{print "Nombre:", $1, "- Edad:", $2}' personas.txt
  1. Filtra las personas mayores de 24 años:
awk '$2 > 24 {print $1, "tiene", $2, "años"}' personas.txt
  1. Calcula la media de edades:
awk '{suma += $2} END {print "Media de edad:", suma/NR}' personas.txt

END es un bloque especial que se ejecuta una sola vez, después de procesar todas las líneas.

  1. Usa un separador distinto con -F:
printf "nombre:edad:ciudad\nJuan:25:Madrid\nMaria:30:Sevilla\n" > datos.csv
awk -F: '{print $1, "vive en", $3}' datos.csv

-F: indica que el separador de campos es : en lugar del espacio.

Dato curioso: awk es en realidad un lenguaje de programación completo. Con él puedes hacer bucles, condicionales y operaciones matemáticas directamente desde la terminal. 😄


🛠️ Ejercicios prácticos

  1. grep: Crea un archivo log.txt con 10 líneas mezcladas y usa grep para filtrar solo las que contienen "ERROR".
  2. sed: Usa sed para reemplazar todas las ocurrencias de tu nombre en un archivo de texto por "Anónimo".
  3. awk: Crea un archivo CSV con nombre, edad y ciudad, y usa awk para mostrar solo las personas mayores de 25 años.
  4. Regex: Usa grep -E para encontrar todas las líneas de un archivo que contengan una dirección IP (formato N.N.N.N).
  5. Desafío: Combina grep, sed y awk en un pipeline para: filtrar líneas con "ERROR" de un log, sustituir "ERROR" por "FALLO" y mostrar solo la segunda columna del resultado.

📝 Evaluación

Cuestionario (5 preguntas):

  1. ¿Qué diferencia hay entre grep y grep -E?
  2. ¿Cómo sustituyes texto en todas las ocurrencias de una línea con sed?
  3. ¿Para qué sirve $2 en un comando de awk?
  4. ¿Qué hace ^ en una expresión regular?
  5. ¿Por qué es mejor usar printf que echo para crear archivos multilínea?

Tarea práctica:

Crea un script procesa.sh que: - Genere un archivo empleados.txt con al menos 5 líneas en formato nombre edad departamento. - Use grep para filtrar los del departamento "IT". - Use awk para calcular la edad media de todos los empleados. - Guarde los resultados en informe.txt.

Entrega: El script, el archivo empleados.txt y el informe.txt generado.

🎬 Vídeo con la solución de la evaluación: Próximamente.


🎉 Recursos adicionales

Tip: Practica grep, sed y awk por separado hasta que te sientas cómodo con cada uno. Luego empieza a combinarlos con pipes. 💡


🚀 Siguientes pasos

¡Felicidades por completar el Módulo 4! En el Módulo 5 aprenderás a organizar tu código en funciones reutilizables, dominarás los bucles avanzados (while, until) y automatizarás tareas con cron. ¡La organización es el siguiente nivel! ✍️