En la lección anterior aprendiste a mover ficheros de sitio; ahora vas a aprender a leer lo que hay dentro y a hacerles preguntas. Esta es, con diferencia, la lección más rentable del módulo: los 40 minutos diarios que el equipo de Veloz Envíos pierde elaborando el informe manual se van casi enteros en abrir app.log a mano, contar errores con el dedo y buscar ciudades en envios.csv con el buscador del editor. Al terminar esta lección harás cada una de esas cosas en un segundo, y con las herramientas que verás aquí ya podrás responder preguntas reales sobre el estado del servidor.
Contenido
- El paradigma Unix: texto plano en flujos de líneas
- Ver ficheros enteros:
cat,tac,nl - Ver ficheros grandes:
less,head,tailytail -f - Contar con
wc - Buscar con
grep - Extraer columnas con
cut - Ordenar y contar:
sortyuniq - Transformar con
try presentar concolumn
- El paradigma Unix: texto plano en flujos de líneas
Antes de un solo comando, entiende la idea que hace que todo esto encaje. En Unix, casi todo se representa como texto plano organizado en líneas: la configuración del sistema, los registros de la aplicación, la salida de los comandos y los datos de negocio. Y existe un conjunto de programas pequeños, cada uno experto en una transformación de líneas, diseñados para combinarse entre sí.
Las tres consecuencias prácticas:
- Una línea es un registro. Contar líneas es contar sucesos; filtrar líneas es filtrar sucesos.
- Los programas no saben de formatos.
grepno sabe qué es un log nicutqué es un CSV. Trabajan sobre líneas y columnas, y eso los hace universales. - La salida de uno es la entrada de otro. Es el principio de las tuberías, que formalizaremos en 02-04. Aquí usaremos
|de forma puntual, y basta con leerlo como «pasa el resultado al siguiente comando».
Trabajaremos sobre los tres ficheros de Veloz Envíos: app.log (FECHA HORA [NIVEL] mensaje, un evento por línea), acceso.log (formato combinado, una petición HTTP por línea) y envios.csv (un envío por línea, con cabecera y separador ,).
- Ver ficheros enteros:
cat, tac, nl
cat, tac, nlcat (concatenate) vuelca el contenido de uno o varios ficheros en pantalla:
id_envio,fecha,ciudad,repartidor,estado,importe E-10234,2026-08-03,Valencia,alopez,entregado,14.50 E-10235,2026-08-03,Sevilla,mgarcia,incidencia,22.00 E-10236,2026-08-03,Bilbao,jruiz,en_reparto,9.75
Su nombre viene de su segunda función: concatenar varios ficheros en un solo flujo, útil para procesar todo el histórico de golpe con cat /srv/veloz/datos/historico/2026/08/*.csv (los comodines se ven en 02-05). Opciones que merecen recordarse: -n numera todas las líneas, -b numera solo las no vacías y -A muestra los caracteres invisibles (tabuladores como ^I, fin de línea como $), imprescindible cuando un fichero «parece correcto» pero un programa lo rechaza.
Dos parientes cercanos: tac imprime las líneas en orden inverso (muy práctico en logs, donde lo reciente está al final; tac app.log | head -5 da los 5 eventos más recientes empezando por el último) y nl, que numera con formato configurable.
Advertencia importante: nunca hagas cat de un fichero grande. Un app.log de 200 MB inundará tu terminal durante minutos. Para eso están less, head y tail.
- Ver ficheros grandes:
less, head y tail
less, head y tailless abre el fichero en un visor paginado sin cargarlo entero en memoria; es la herramienta por defecto para inspeccionar cualquier cosa.
| Tecla | Acción |
|---|---|
Espacio / b |
Página adelante / atrás |
g / G |
Ir al principio / al final del fichero |
/texto / ?texto |
Buscar hacia adelante / atrás; n siguiente, N anterior |
-N |
Mostrar u ocultar números de línea |
F |
Seguir el fichero en vivo (como tail -f); Ctrl-C para salir del modo |
q |
Salir |
Reconocerás estas teclas: son las mismas de man, porque man usa less como paginador (lección 01-05).
head muestra el principio y tail el final. Ambos usan 10 líneas por defecto y aceptan -n NÚMERO:
head -n 3 /srv/veloz/datos/envios.csv # cabecera + 2 registros
tail -n 20 /var/log/veloz/app.log # los 20 últimos eventos
tail -n +2 /srv/veloz/datos/envios.csv # DESDE la línea 2: el CSV sin cabeceraEsa tercera forma, tail -n +2, es un truco que usarás constantemente: descarta la cabecera del CSV para que los comandos siguientes solo vean datos.
tail -f: ver el log en vivo
La opción estrella para operaciones. -f (follow) deja el comando abierto imprimiendo cada línea nueva según se escribe:
2026-08-03 11:04:15 [WARN] latencia elevada en consulta de repartidores (812ms) 2026-08-03 11:04:19 [ERROR] timeout al conectar con pasarela de pago
Se sale con Ctrl-C. Este es el comando que tendrás abierto en una ventana mientras despliegas un cambio en veloz-api. Una variante mejor para logs que rotan es tail -F: si el fichero se renombra y se crea uno nuevo (rotación diaria), -F sigue el nombre y continúa mostrando el log actual, mientras que -f se queda pegado al fichero antiguo.
- Contar con
wc
wcwc (word count) cuenta líneas, palabras y bytes: esos son los tres números. -l (líneas) es el que usarás el 95 % de las veces: cuenta eventos, peticiones o registros. Existen también -w (palabras), -c (bytes) y -m (caracteres, que difiere de -c con acentos en UTF-8).
Con wc -l < /srv/veloz/datos/envios.csv obtienes 1247 a secas. Ese < es una redirección de entrada (02-04) y hace que wc no imprima el nombre del fichero, solo el número. Recuerda restar 1 por la cabecera: hay 1246 envíos.
- Buscar con
grep
grepgrep filtra las líneas que contienen un patrón. Es la herramienta más usada de todo Unix.
Eso imprime, una por línea, cada evento del log cuyo texto contenga ERROR. Las opciones que necesitas de verdad:
| Opción | Efecto | Ejemplo real |
|---|---|---|
-i |
Ignora mayúsculas/minúsculas | grep -i valencia envios.csv |
-n |
Muestra el número de línea | Localizar el evento en el fichero |
-c |
Solo cuenta las líneas que casan | grep -c ERROR app.log |
-v |
Invierte: muestra las que NO casan | Excluir el ruido de [INFO] |
-w |
Palabra completa | grep -w jruiz no casa con jruizb |
-r / -l |
Recursivo por un directorio / solo los nombres de fichero que casan | grep -rl ERROR /var/log/veloz/ |
-A n / -B n / -C n |
n líneas después / antes / de contexto a ambos lados | Ver qué rodeó al error |
-F |
Patrón literal, sin caracteres especiales | Buscar GET /api/envios?id=1.2 |
-o |
Imprime solo la parte que casa, no la línea entera | Extraer valores |
grep -c ERROR /var/log/veloz/app.log devuelve 37: treinta y siete errores hoy, un dato que antes se obtenía contando a ojo.
2158-2026-08-03 09:12:42 [INFO] iniciando cobro del envio E-10188 2159-2026-08-03 09:12:43 [WARN] reintento 1 de 3 hacia la pasarela 2160:2026-08-03 09:12:44 [ERROR] timeout al conectar con pasarela de pago 2161-2026-08-03 09:12:45 [INFO] cobro marcado como pendiente
El contexto es lo que convierte un error suelto en un diagnóstico: la línea con : es la que casó, las de - son el contexto, y juntas cuentan la historia completa.
grep -v "\[INFO\]" /var/log/veloz/app.log | tail -5 # solo lo que no es rutina
grep -F "GET /api/envios?ciudad=Valencia" acceso.log | wc -l # peticiones a esa rutaSobre los patrones: grep interpreta el patrón como una expresión regular, un lenguaje de coincidencias con caracteres especiales (., *, [, ^, $...). Por eso arriba hay que escapar los corchetes de [INFO], y por eso -F —que desactiva toda interpretación— es tan útil cuando buscas una cadena literal con puntos, barras o interrogaciones. Las expresiones regulares completas son un tema en sí mismo y las estudiaremos a fondo en 05-04; con las opciones de esta tabla y patrones literales cubres el 80 % del trabajo diario.
- Extraer columnas con
cut
cutcut recorta cada línea y devuelve solo los campos que pides. Para un CSV, -d define el delimitador y -f los campos (empezando en 1).
Recordemos la cabecera de envios.csv: id_envio,fecha,ciudad,repartidor,estado,importe → campos 1 a 6.
Observa que la primera línea de la salida es ciudad: la cabecera del CSV también se procesa como un registro más.
cut -d, -f3,5 /srv/veloz/datos/envios.csv # campos 3 y 5 (ciudad y estado)
cut -d, -f4-6 /srv/veloz/datos/envios.csv # rango del 4 al 6
cut -c1-10 /var/log/veloz/app.log # por posición: la fecha del logEse último uso, -c, corta por posición de carácter en lugar de por campo, y es muy práctico en logs de formato fijo como app.log, donde los 10 primeros caracteres son siempre la fecha.
Su gran limitación: cut no entiende comillas. Si un campo de un CSV contuviera una coma entre comillas ("Valencia, centro"), el recuento de campos se descuadraría. Para CSV complejos harán falta awk (06-01) o herramientas específicas; para el formato controlado de Veloz Envíos, cut es perfecto.
- Ordenar y contar:
sort y uniq
sort y uniqsort ordena líneas alfabéticamente por defecto:
| Opción | Efecto |
|---|---|
-n |
Orden numérico (sin él, 10 va antes que 9) |
-r |
Orden inverso |
-u |
Elimina duplicados tras ordenar |
-t C |
Define el separador de campos |
-k N |
Ordena por el campo N (-k3 por el tercero; -k6 -n por importe) |
Extraer la columna, quitar la cabecera y ordenar eliminando repetidos: ahí tienes la lista de ciudades operativas.
uniq colapsa líneas adyacentes iguales, y -c antepone cuántas había. Esa palabra, adyacentes, es la clave: uniq casi siempre va precedido de sort, porque si los duplicados no están juntos no los detecta. La combinación sort | uniq -c | sort -rn es probablemente la más útil de todo Unix:
Léelo de izquierda a derecha: extrae la ciudad → quita la cabecera → ordena para agrupar → cuenta cada grupo → ordena por número descendente. Acabas de construir un ranking en una sola línea. Con sort -t, -k6 -rn sobre el fichero completo obtendrías, en cambio, los envíos de mayor importe.
- Transformar con
tr y presentar con column
tr y presentar con columntr (translate) sustituye o elimina caracteres, uno a uno. No trabaja con ficheros como argumento: siempre lee de la entrada.
| Uso | Comando | Para qué |
|---|---|---|
| Cambiar mayúsculas | tr 'a-z' 'A-Z' |
Normalizar antes de comparar |
| Sustituir separador | tr ',' '\t' |
Convertir CSV en TSV |
| Borrar caracteres | tr -d '\r' |
Limpiar finales de línea de Windows |
| Comprimir repeticiones | tr -s ' ' |
Colapsar espacios múltiples en uno |
El tr -d '\r' merece atención: cuando un CSV se ha editado en Windows, cada línea termina en \r\n, y ese \r invisible hace que comparaciones aparentemente idénticas fallen. Si un filtro no encuentra nada que «debería estar ahí», comprueba el fichero con cat -A.
column -t alinea la salida en columnas para que un humano pueda leerla:
id_envio fecha ciudad repartidor estado importe E-10234 2026-08-03 Valencia alopez entregado 14.50 E-10235 2026-08-03 Sevilla mgarcia incidencia 22.00 E-10236 2026-08-03 Bilbao jruiz en_reparto 9.75
-s, indica que el separador de entrada es la coma y -t genera la tabla. Es el toque final de cualquier informe que vaya a leer una persona.
Con estas ocho herramientas ya resuelves la mayoría de preguntas. Cuando necesites calcular sobre las columnas (sumar importes, medias, condiciones por campo) o reescribir el texto con reglas, el siguiente escalón son awk y sed, dos lenguajes completos que ocupan el Módulo 6.
Errores Comunes y Consejos
- Hacer
catde un log enorme. Usaless,headotail. Si ya lo has lanzado,Ctrl-C. - Usar
uniqsinsortdelante. Solo colapsa líneas adyacentes; sin ordenar antes, los recuentos salen mal y sin ningún error que te avise. - Ordenar números con
sorta secas. El orden alfabético coloca100antes que9. Para importes o contadores,-nsiempre. - Olvidar la cabecera del CSV. Aparecerá como una ciudad más llamada
ciudad;tail -n +2la elimina. - Pelearse con las expresiones regulares sin querer. Si tu patrón contiene
.,[,?o/, usagrep -F. Y entail, recuerda que en logs que rotan a medianoche la opción correcta es-F, no-f. - Contar con
grep -ccreyendo que cuenta coincidencias. Cuenta líneas que casan: dos apariciones en la misma línea suman una. Para contar apariciones,grep -o patron fichero | wc -l.
Ejercicios
Ejercicio 1 — Diagnóstico rápido del día. Sobre /var/log/veloz/app.log: (1) cuenta cuántos eventos hay en total; (2) cuántos son de nivel ERROR; (3) muestra los 5 eventos más recientes que no sean [INFO]; (4) muestra el primer ERROR del fichero con las 2 líneas anteriores y las 2 posteriores.
Ejercicio 2 — Ranking de incidencias por ciudad. Sobre /srv/veloz/datos/envios.csv, construye una única línea que muestre cuántas incidencias hay por ciudad, ordenadas de más a menos. Explica cada paso.
Ejercicio 3 — Informe legible de repartidores. Obtén la lista de repartidores distintos que aparecen en el CSV y, por separado, el número de envíos de cada uno presentado en forma de tabla alineada.
Soluciones
Solución al Ejercicio 1
wc -l < /var/log/veloz/app.log # 1
grep -c ERROR /var/log/veloz/app.log # 2
grep -v "\[INFO\]" /var/log/veloz/app.log | tail -5 # 3
grep -n -C 2 ERROR /var/log/veloz/app.log | head -5 # 4En (3), grep -v descarta la rutina y tail -5 se queda con lo más reciente, porque los logs crecen por el final. En (4), -C 2 añade dos líneas de contexto a cada lado y head -5 recorta al primer bloque (2 antes + la coincidencia + 2 después). El -n numera las líneas para poder localizarlas después con less -N.
Solución al Ejercicio 2
Paso a paso: grep incidencia se queda solo con las líneas cuyo estado es incidencia (y de paso elimina la cabecera, que no contiene esa palabra); cut -d, -f3 extrae la ciudad; sort agrupa las repetidas; uniq -c cuenta cada grupo; sort -rn ordena por el número descendente. Un filtro más estricto sería grep ',incidencia,' para asegurar que la palabra está en el campo de estado y no dentro de otro campo.
Solución al Ejercicio 3
# Repartidores distintos → alopez, jruiz, mgarcia
cut -d, -f4 /srv/veloz/datos/envios.csv | tail -n +2 | sort -u
# Envíos por repartidor, en tabla alineada
cut -d, -f4 /srv/veloz/datos/envios.csv | tail -n +2 | sort | uniq -c | sort -rn | column -tAquí column -t va sin -s, porque la salida de uniq -c está separada por espacios, no por comas: -t detecta espacios por defecto. Es un buen recordatorio de que cada comando de la cadena cambia el formato, y hay que ajustar el siguiente en consecuencia.
Conclusión
Acabas de adquirir el núcleo del procesamiento de texto en Unix: sabes ver ficheros con cat, less, head y tail, vigilar un log en vivo con tail -f, contar con wc -l, filtrar con grep y sus opciones de contexto e inversión, extraer columnas con cut, ordenar y agregar con sort y uniq -c, normalizar con tr y presentar con column -t. Sobre todo, has visto la lógica que los une: cada programa hace una transformación de líneas y encadenarlos responde preguntas que ningún comando resuelve solo.
Fíjate en cuánto has ganado ya: el ranking de incidencias por ciudad, que antes exigía abrir el CSV y contar a mano, es ahora una línea que tarda milisegundos.
Antes de encadenar filtros con soltura hay que resolver una cuestión previa, y es de quién es cada fichero y quién puede leerlo o escribirlo. En la lección 02-03 estudiarás los permisos y la propiedad: por qué veloz-api puede escribir en /var/log/veloz y tu usuario no, cómo hacer ejecutable el primer script de ~/veloz-ops/bin y cómo proteger con permiso 600 el fichero de configuración que pronto contendrá credenciales.
Curso de Programación en Bash
Módulo 1: Introducción a Bash
- ¿Qué es Bash?
- Configurando tu Entorno
- Navegación Básica en la Línea de Comandos
- Entendiendo el Shell
- Encontrar Ayuda: man, help y --help
Módulo 2: Comandos Básicos de Bash
- Operaciones con Archivos y Directorios
- Comandos de Procesamiento de Texto
- Permisos y Propiedad de Archivos
- Redirección y Tuberías
- Comodines y Expansión de Rutas
- Historial y Atajos de Teclado
Módulo 3: Fundamentos de Scripting
- Creando y Ejecutando un Script
- Variables y Constantes
- Operadores Básicos
- Sentencias Condicionales
- Argumentos y Entrada del Usuario
- Comillas, Expansión y Sustitución
Módulo 4: Scripting Intermedio
- Bucles en Bash
- Funciones en Bash
- Arrays y Arrays Asociativos
- Manipulación de Cadenas
- La Sentencia case y los Menús Interactivos
- Aritmética y Cálculos Numéricos
Módulo 5: Técnicas Avanzadas de Scripting
- Operaciones Avanzadas con Archivos
- Gestión de Procesos
- Manejo de Errores y Depuración
- Expresiones Regulares
- Entrada/Salida Avanzada: Descriptores y Here-Documents
- Scripts Modulares y Librerías Reutilizables
Módulo 6: Trabajando con Herramientas Externas
Módulo 7: Automatización y Programación
- Trabajos Cron
- Automatizando Tareas
- Scripts de Respaldo y Restauración
- Monitoreo y Registro
- Servicios y Temporizadores con systemd
- Automatización Remota con SSH
Módulo 8: Mejores Prácticas y Optimización
- Escribiendo Código Legible
- Optimizando Scripts en Bash
- Consideraciones de Seguridad
- Control de Versiones con Git
- Análisis Estático con ShellCheck y shfmt
- Pruebas Automatizadas con Bats
- Portabilidad: POSIX sh frente a Bashismos
