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

  1. El paradigma Unix: texto plano en flujos de líneas
  2. Ver ficheros enteros: cat, tac, nl
  3. Ver ficheros grandes: less, head, tail y tail -f
  4. Contar con wc
  5. Buscar con grep
  6. Extraer columnas con cut
  7. Ordenar y contar: sort y uniq
  8. Transformar con tr y presentar con column

  1. 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. grep no sabe qué es un log ni cut qué 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 ,).

  1. Ver ficheros enteros: cat, tac, nl

cat (concatenate) vuelca el contenido de uno o varios ficheros en pantalla:

cat /srv/veloz/datos/envios.csv
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.

  1. Ver ficheros grandes: less, head y tail

less abre el fichero en un visor paginado sin cargarlo entero en memoria; es la herramienta por defecto para inspeccionar cualquier cosa.

less /var/log/veloz/acceso.log
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 cabecera

Esa 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:

tail -f /var/log/veloz/app.log
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.

  1. Contar con wc

wc /var/log/veloz/app.log
  18432  147891  2103455 /var/log/veloz/app.log

wc (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.

  1. Buscar con grep

grep filtra las líneas que contienen un patrón. Es la herramienta más usada de todo Unix.

grep ERROR /var/log/veloz/app.log

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.

grep -n -C 2 "pasarela de pago" /var/log/veloz/app.log | head -8
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 ruta

Sobre 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.

  1. Extraer columnas con cut

cut 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.

cut -d, -f3 /srv/veloz/datos/envios.csv | head -4
ciudad
Valencia
Sevilla
Bilbao

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 log

Ese ú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.

  1. Ordenar y contar: sort y uniq

sort 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)
cut -d, -f3 /srv/veloz/datos/envios.csv | tail -n +2 | sort -u
Bilbao
Madrid
Sevilla
Valencia

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:

cut -d, -f3 /srv/veloz/datos/envios.csv | tail -n +2 | sort | uniq -c | sort -rn
    412 Madrid
    338 Valencia
    271 Sevilla
    225 Bilbao

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.

  1. Transformar con tr y presentar con column

tr (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:

head -5 /srv/veloz/datos/envios.csv | column -t -s,
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 cat de un log enorme. Usa less, head o tail. Si ya lo has lanzado, Ctrl-C.
  • Usar uniq sin sort delante. Solo colapsa líneas adyacentes; sin ordenar antes, los recuentos salen mal y sin ningún error que te avise.
  • Ordenar números con sort a secas. El orden alfabético coloca 100 antes que 9. Para importes o contadores, -n siempre.
  • Olvidar la cabecera del CSV. Aparecerá como una ciudad más llamada ciudad; tail -n +2 la elimina.
  • Pelearse con las expresiones regulares sin querer. Si tu patrón contiene ., [, ? o /, usa grep -F. Y en tail, recuerda que en logs que rotan a medianoche la opción correcta es -F, no -f.
  • Contar con grep -c creyendo 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 # 4

En (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

grep incidencia /srv/veloz/datos/envios.csv | cut -d, -f3 | sort | uniq -c | sort -rn
    47 Madrid
    31 Sevilla
    22 Valencia
    18 Bilbao

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 -t
487  alopez
412  mgarcia
347  jruiz

Aquí 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

Módulo 2: Comandos Básicos de Bash

Módulo 3: Fundamentos de Scripting

Módulo 4: Scripting Intermedio

Módulo 5: Técnicas Avanzadas de Scripting

Módulo 6: Trabajando con Herramientas Externas

Módulo 7: Automatización y Programación

Módulo 8: Mejores Prácticas y Optimización

Módulo 9: Proyectos del Mundo Real

© Copyright 2026. Todos los derechos reservados