Unidad 7: Expresiones Regulares y Filtrado de Datos

Introducción a expresiones regulares

Una expresión regular (regex) es una forma de describir un patrón dentro de un texto.

En lugar de buscar una palabra exacta, podemos buscar una estructura.

Por ejemplo:

  • encontrar cualquier número,

  • buscar palabras que empiecen con cierta letra,

  • validar si un texto tiene un formato correcto (como una CURP, correo electrónico o nombre de archivo).

🔍 Ejemplo simple

Si queremos encontrar números en un texto:

[0-9]

Esto significa:
“cualquier carácter entre 0 y 9”.

Si queremos encontrar varios números seguidos:

[0-9]+

El símbolo + significa “uno o más”.

🧠 Idea clave

Las expresiones regulares no buscan texto literal, buscan patrones.

🔧 Uso de regex101

Para aprender y probar expresiones regulares, vamos a usar:

👉 https://regex101.com/

Esta herramienta permite:

  • probar expresiones en tiempo real,

  • ver qué partes del texto coinciden,

  • entender cómo funciona cada parte del patrón.

🧪 Cómo usar regex101

Ejemplo práctico: Validar una CURP

La CURP es un excelente ejemplo porque tiene una estructura fija.

Ejemplo:

PEGA850912HMCRRL09

📌 Estructura simplificada de una CURP

  • 4 letras iniciales

  • 6 números (fecha: año, mes, día)

  • 1 letra (sexo: H o M)

  • 5 letras

  • 2 caracteres alfanuméricos

🧩 Construcción paso a paso del patrón de la CURP

Paso 1: cuatro letras al inicio

^[A-Z]{4}
  • ^ → inicio de la línea

  • [A-Z] → letras mayúsculas

  • {4} → exactamente 4 letras

Paso 2: agregar seis números (fecha)

^[A-Z]{4}[0-9]{6}

Paso 3: agregar el sexo

^[A-Z]{4}[0-9]{6}[HM]
  • [HM] → solo permite H o M

Paso 4: agregar letras internas

^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}

Paso 5: agregar los últimos caracteres

^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$
  • [A-Z0-9]{2} → dos caracteres alfanuméricos

  • $ → fin de la línea

Elementos de regex usando fechas

Trabajaremos con ejemplos como:

23/03/2026
23-03-2026
23 03 2026
23-03-26

🧠 Idea clave

Las expresiones regulares describen la forma de un texto, no su significado.

🔤 Clases de caracteres

\d → dígitos

\d{2}/\d{2}/\d{4}

👉 coincide con:

23/03/2026

\s → espacios

\d{2}\s\d{2}\s\d{4}

👉 coincide con:

23 03 2026

\S → no espacio

\S+

👉 coincide con cualquier cosa que no tenga espacios

\w → letras, números o _

\w+

👉 en fechas no es ideal porque incluye letras también

\W → no letras ni números

\W

👉 coincide con separadores como:

/  -

🔧 Metacaracteres importantes

^ → inicio

^\d{2}/\d{2}/\d{4}

👉 la fecha debe empezar así

$ → final

\d{2}/\d{2}/\d{4}$

👉 la fecha debe terminar así

+ → uno o más

\d+

👉 uno o más números

* → cero o más

\d*

👉 puede haber números o no

{n} → cantidad exacta

\d{2}

👉 exactamente 2 dígitos

🧩 Clases y opciones

[ ] → opciones

[/-]

👉 acepta:

23/03/2026
23-03-2026

| → o

/|-

👉 igual que [/-] pero menos práctico

🧩 Grupos ( )

Sirven para agrupar partes de la expresión.

(\d{2})/(\d{2})/(\d{4})

👉 divide en:

  • día

  • mes

  • año

Reutilizar grupos

^(\d{2})([/-])(\d{2})\2(\d{4})$

👉 asegura que el separador sea el mismo

✔ acepta:

23/03/2026
23-03-2026

❌ rechaza:

23/03-2026

🔐 Escapar caracteres

Algunos símbolos tienen significado especial.

Punto .

.

👉 significa “cualquier carácter”

Buscar un punto literal

\.

Ejemplo con fechas

\d{2}\.\d{2}\.\d{4}

👉 coincide con:

23.03.2026

🧪 Ejemplo integrador

^(0[1-9]|[12][0-9]|3[01])[/-](0[1-9]|1[0-2])[/-]\d{4}$

👉 valida:

  • día entre 01 y 31

  • mes entre 01 y 12

  • año de 4 dígitos

  • separador / o -

🚀 Conexión con bioinformática

Las expresiones regulares se usan para:

  • encontrar secuencias específicas en FASTA/FASTQ,

  • identificar patrones en nombres de archivos,

  • filtrar resultados de BLAST,

  • validar formatos de datos.

  • etc.

Uso de expresiones regulares con grep

grep permite buscar líneas que coincidan con un patrón dentro de un archivo de texto.

En otras palabras:

  • regex101 nos ayuda a entender y probar la expresión regular,

  • grep nos ayuda a aplicarla en archivos reales desde Bash.

¿Qué hace grep?

La forma más simple de grep es:

grep "patron" archivo.txt

Esto busca en el archivo las líneas que coincidan con el patrón indicado.

Crear un archivo de ejemplo

Para trabajar con CURPs, primero podemos crear un archivo de texto:

nano curps.txt

Y pega esto:

PEGA850912HMCRRL09
GODE561231MDFABC08
XXXX000000HNEYYY00
PEGA850912HMCRRL0
PEGA850912HMCRRL099
PEGA850912HMCRRLAA

Guarda el archivo y sal de nano.

Buscar texto literal con grep

Primero podemos usar grep sin expresión regular compleja, solo buscando texto literal.

Por ejemplo, buscar las líneas que contengan PEGA:

grep "PEGA" curps.txt

Esto devolverá las líneas donde aparezca esa cadena.

Buscar líneas que empiecen con cierto patrón

Si queremos que la línea empiece con PEGA, usamos ^:

grep "^PEGA" curps.txt

Explicación

  • ^ indica inicio de línea.

  • PEGA debe aparecer al comienzo.

Buscar líneas que terminen con un patrón

Si queremos líneas que terminen en 09:

grep "09$" curps.txt

Explicación

  • $ indica final de línea.

Usar una expresión regular con grep

En regex101 probamos una expresión para validar una CURP con estructura general:

^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$

Para usar esa expresión en grep, conviene activar las expresiones regulares extendidas con -E:

grep -E '^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$' curps.txt

Mostrar las líneas inválidas

También podemos pedirle a grep que muestre las líneas que no cumplen el patrón, usando -v:

grep -Ev '^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$' curps.txt

Explicación

  • -E usa expresiones regulares extendidas,

  • -v invierte la búsqueda.

Esto es muy útil para detectar errores en archivos de datos.

Extracción de datos con cut

cut es una herramienta de Bash que permite extraer partes específicas de un archivo de texto.

🧠 ¿Cuándo usar cut?

cut es ideal cuando:

  • los datos tienen una estructura fija (como la CURP),

  • o están organizados en columnas separadas por delimitadores (CSV, TSV).

🔧 Sintaxis básica

Por posiciones (caracteres)

cut -c posiciones archivo.txt

Por columnas (delimitadores)

cut -d "DELIMITADOR" -f columnas archivo.txt

📌 Parte 1: Uso de cut con posiciones

Archivo de ejemplo

nano curps.txt
PEGA850912HMCRRL09
GODE561231MDFABC08
XXXX000000HNEYYY00
PEGA850912HMCRRL0
PEGA850912HMCRRL099
PEGA850912HMCRRLAA

🧬 Estructura de una CURP

Posición Contenido
1–4 Letras iniciales
5–10 Fecha
11 Sexo
12–13 Entidad
14–16 Consonantes
17–18 Homoclave

Extraer la fecha

cut -c5-10 curps.txt

Extraer el sexo

cut -c11 curps.txt

Extraer entidad federativa

cut -c12-13 curps.txt

Extraer múltiples posiciones

cut -c1-4,11 curps.txt

📌 Parte 2: Uso de cut con delimitadores

Muchos archivos tienen columnas separadas por:

  • espacios

  • comas (CSV)

  • tabuladores (TSV)

🔧 Sintaxis

cut -d "DELIMITADOR" -f columnas archivo.txt

Ejemplo 1: archivo con espacios

nano personas_curp.txt
Ana PEGA850912HMCRRL09
Luis GODE561231MDFABC08
Marta XXXX000000HNEYYY00
Juan PEGA850912HMCRRL0

Extraer CURP

cut -d " " -f2 personas_curp.txt

Extraer nombres

cut -d " " -f1 personas_curp.txt

Ejemplo 2: archivo CSV

nano datos.csv
nombre,curp,edad
Ana,PEGA850912HMCRRL09,38
Luis,GODE561231MDFABC08,60
Marta,XXXX000000HNEYYY00,25

Extraer CURP

cut -d "," -f2 datos.csv

Extraer nombre y edad

cut -d "," -f1,3 datos.csv

Ejemplo 3: archivo TSV

nano datos.tsv
nombre  curp  sexo
Ana PEGA850912HMCRRL09  H
Luis  GODE561231MDFABC08  M

Extraer CURP

cut -d $'\t' -f2 datos.tsv

Extraer sexo

cut -d $'\t' -f3 datos.tsv

🔬 Ejemplo bioinformático

Archivo tipo BLAST:

seq1    subject1    98.5    150
seq2    subject2    87.2    120
seq3    subject3    99.1    200

Extraer identidad (%)

cut -d $'\t' -f3 archivo.txt

Extraer ID y longitud

cut -d $'\t' -f1,4 archivo.txt
cut -d "," -f2 datos.csv | cut -c11

Transformación de datos con sed

sed (stream editor) procesa texto línea por línea y permite:

  • reemplazar patrones

  • eliminar contenido

  • formatear texto

  • editar archivos de manera automática

🔧 Sintaxis básica

sed 's/patron/reemplazo/' archivo.txt

Explicación

  • s → significa substitute (sustituir)

  • patron → lo que queremos buscar

  • reemplazo → lo que queremos poner

Archivo de trabajo

Seguimos usando:

curps.txt
PEGA850912HMCRRL09
GODE561231MDFABC08
XXXX000000HNEYYY00
PEGA850912HMCRRL0
PEGA850912HMCRRL099
PEGA850912HMCRRLAA

📌 Parte 1: Reemplazos básicos

Cambiar letras por minúsculas

sed 's/.*/\L&/' curps.txt

Explicación

  • .* → toda la línea

  • & → representa la coincidencia completa

  • \L → convierte a minúsculas

Reemplazar texto específico

sed 's/PEGA/XXXX/' curps.txt

Reemplazar todas las coincidencias en la línea

sed 's/A/X/g' curps.txt

Explicación

  • g → reemplaza todas las coincidencias, no solo la primera

📌 Parte 2: Uso de expresiones regulares en sed

Para trabajar mejor con patrones complejos usamos -E:

sed -E 's/patron/reemplazo/' archivo.txt

Separar la CURP en bloques

sed -E 's/^([A-Z]{4})([0-9]{6})([HM])([A-Z]{2})([A-Z]{3})([A-Z0-9]{2})$/\1-\2-\3-\4-\5-\6/' curps.txt

Explicación

Se crean grupos:

Grupo Contenido
\1 primeras 4 letras
\2 fecha
\3 sexo
\4 entidad
\5 consonantes
\6 final

Y se reconstruye con guiones:

PEGA-850912-H-MC-RRL-09

Marcar CURPs válidas

sed -E 's/^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$/& -> VALIDA/' curps.txt

Marcar CURPs inválidas

sed -E '/^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$/! s/.*/& -> INVALIDA/' curps.txt

📌 Parte 3: Filtrar con sed

Aunque grep es mejor para filtrar, sed también puede hacerlo.

Mostrar solo CURPs válidas

sed -En '/^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$/p' curps.txt

Explicación

  • -n → no imprime automáticamente

  • p → imprime solo las coincidencias

Eliminar líneas inválidas

sed -E '/^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$/!d' curps.txt

📌 Parte 4: Eliminar o modificar partes de texto

Eliminar los primeros 4 caracteres

sed 's/^....//' curps.txt

Eliminar números

sed 's/[0-9]//g' curps.txt

Eliminar líneas vacías

sed '/^$/d' archivo.txt

📌 Parte 5: Edición de archivos (in-place)

Para modificar directamente un archivo:

sed -i 's/PEGA/TEST/' curps.txt

⚠️ Esto modifica el archivo original

🔗 Combinar sed con otras herramientas

Formatear solo CURPs válidas

grep -E '^[A-Z]{4}[0-9]{6}[HM][A-Z]{5}[A-Z0-9]{2}$' curps.txt | \ sed -E 's/^([A-Z]{4})([0-9]{6})([HM])([A-Z]{2})([A-Z]{3})([A-Z0-9]{2})$/\1-\2-\3-\4-\5-\6/'

Extraer y formatear desde CSV

cut -d "," -f2 datos.csv | \ sed -E 's/^([A-Z]{4})([0-9]{6})([HM])([A-Z]{2})([A-Z]{3})([A-Z0-9]{2})$/\1-\2-\3-\4-\5-\6/'

⚠️ Errores comunes

Olvidar -E

Sin -E, los {} y () no funcionan igual.

No usar comillas correctas

Siempre usar:

's/.../.../'

Modificar archivos sin querer

sed -i

👉 usar con cuidado

Introducción a awk (nivel básico)

awk es una herramienta que permite:

👉 analizar, filtrar y procesar datos línea por línea

Funciona leyendo un archivo, separando cada línea en columnas y aplicando acciones sobre ellas.

⚠️ Importante

awk es muy potente, pero también:

👉 tiene una sintaxis un poco más compleja que grep, cut o sed.

💡 Por eso, en esta sección veremos solo lo básico, suficiente para:

  • extraer información

  • hacer filtros simples

  • generar salidas útiles

🔧 Sintaxis básica

awk '{accion}' archivo.txt

📌 Conceptos clave

Dentro de awk:

  • $0 → toda la línea

  • $1 → primera columna

  • $2 → segunda columna

Archivo de trabajo

curps.txt
PEGA850912HMCRRL09
GODE561231MDFABC08
XXXX000000HNEYYY00
PEGA850912HMCRRL0

📌 Ejemplos simples

Mostrar todas las líneas

awk '{print $0}' curps.txt

Extraer sexo (posición 11)

awk '{print substr($0,11,1)}' curps.txt

Mostrar CURP + sexo

awk '{print $0, "-> sexo:", substr($0,11,1)}' curps.txt

📌 Filtrar con awk

Mostrar solo hombres

awk 'substr($0,11,1)=="H"' curps.txt

Mostrar solo CURPs con longitud correcta

awk 'length($0)==18' curps.txt

📌 Un ejemplo con lógica (if)

awk '{
  if (length($0)==18)
    print $0, "-> correcta"
  else
    print $0, "-> incorrecta"
}' curps.txt

🧠 Idea clave

Mientras que:

  • grep → filtra por patrones

  • cut → corta columnas

  • sed → modifica texto

👉 awk permite hacer todo eso pero con lógica

Búsqueda de archivos con find

find permite localizar archivos o carpetas según:

  • nombre

  • tipo (archivo o carpeta)

  • tamaño

  • fecha

  • permisos

🔧 Sintaxis básica

find ruta opciones

Ejemplo básico

Buscar todos los archivos en el directorio actual:

find .

Buscar por nombre

Buscar archivos .txt

find . -name "*.txt"

Buscar archivos FASTA

find . -name "*.fasta"

Buscar archivos FASTQ comprimidos

find . -name "*.fastq.gz"

⚠️ Importante

  • -name usa comodines (glob), no regex completas:

  • * → cualquier número de caracteres

  • ? → un solo carácter

Ejemplos

find . -name "sample?.fq"
find . -name "A*"

📌 Buscar por tipo

Solo archivos

find . -type f

Solo directorios

find . -type d

Buscar archivos FASTA únicamente

find . -type f -name "*.fasta"

📌 Buscar con expresiones regulares

Aunque no es lo más común, find también puede usar regex:

find . -regex '.*\.txt$'

Ejemplo

find . -regex '.*sample[0-9]+\.fq'

⚠️ Nota importante

  • -regex evalúa la ruta completa, no solo el nombre

  • por eso se usa .* al inicio

📌 Diferencia clave

Opción Tipo de patrón
-name comodines (*, ?)
-regex expresiones regulares

👉 En la práctica, -name es el más usado.

📌 Buscar por tamaño

Archivos mayores a 1 MB

find . -size +1M

Archivos menores a 100 KB

find . -size -100k

📌 Buscar por tiempo

Archivos modificados en los últimos 2 días

find . -mtime -2

📌 Ejecutar acciones con find

find se vuelve muy poderoso cuando se combina con acciones.

Mostrar detalles con ls

find . -name "*.txt" -exec ls -lh {} \;

⚠️ Eliminar archivos

find . -name "*.tmp" -delete

Ejecutar comandos en cada archivo

find . -name "*.fastq.gz" -exec echo "Procesando {}" \;

🔗 Combinar find con otras herramientas

Buscar archivos y aplicar grep

find . -name "*.txt" -exec grep "PEGA" {} \;

Buscar FASTA y contar secuencias

find . -name "*.fasta" -exec grep ">" {} \;

⚠️ Errores comunes

No usar comillas

find . -name *.txt   ❌
find . -name "*.txt" ✅

🚀 Resumen find

Opción Uso
-name buscar por nombre
-type tipo de archivo
-size tamaño
-mtime fecha
-regex usar regex
-exec ejecutar comandos