En el Módulo 1 leíste que en Unix «el texto plano es la interfaz universal». Sonaba a declaración de principios. En la lección anterior viste el mecanismo que la hace posible —tuberías y redirección— y aquí llegan las herramientas que le dan sentido: un conjunto de programas pequeños, escritos hace cuarenta años, que saben recortar, ordenar, contar, sustituir y agregar texto, y que combinados resuelven en una línea lo que en otro entorno exigiría un programa.

Esa es la promesa concreta de esta lección: reservas.csv y acceso.log son ficheros de texto, y Marta necesita informes. Al terminar podrás producirlos sin abrir una hoja de cálculo y sin escribir código, y —más importante— sabrás cuándo estas herramientas dejan de ser la respuesta correcta.

Contenido

  1. cut: recortar columnas
  2. tr: traducir, borrar y comprimir
  3. sort: ordenar de verdad
  4. uniq: contar apariciones
  5. paste, join y comm: comparar listados
  6. sed: el editor de flujo
  7. awk: el lenguaje de los campos
  8. Tabla de decisión: qué herramienta y cuándo
  9. Caso A: informe de facturación para Marta
  10. Caso B y C: rutas con errores e IPs anómalas

  1. cut: recortar columnas

Extrae partes de cada línea, por campos o por caracteres.

Opción Efecto
-d';' delimitador (por defecto, el tabulador)
-f2,4 / -f2-5 campos: lista o rango
-c1-10 por posición de carácter
--complement todo menos lo indicado
--output-delimiter=X separador de la salida
operador@srv-tramontana:~$ head -3 /home/operador/datos/reservas.csv
id;fecha;casa;huesped;noches;importe
1001;2026-07-03;mas-figueres;Nuria Bosch;4;520.00
1002;2026-07-05;can-ventos;Pere Rius;2;240.00
operador@srv-tramontana:~$ cut -d';' -f3,6 /home/operador/datos/reservas.csv | head -2
casa;importe
mas-figueres;520.00

cut es rapidísimo y tiene un límite serio: no entiende delimitadores repetidos. Con un fichero alineado por espacios, cada espacio extra cuenta como un campo vacío:

operador@srv-tramontana:~$ echo 'GET   /reservas   200' | cut -d' ' -f2

Salida vacía: el campo 2 es el espacio entre GET y el siguiente. Para salida separada por espacios variables —que es la de casi cualquier comando— la herramienta correcta es awk, que trata cualquier bloque de blancos como un único separador. cut para formatos con delimitador fijo (CSV, /etc/passwd); awk para todo lo demás.

  1. tr: traducir, borrar y comprimir

tr opera carácter a carácter y solo lee de stdin.

operador@srv-tramontana:~$ echo 'GET   /reservas   200' | tr -s ' ' | cut -d' ' -f2
/reservas
Opción Efecto
tr 'a' 'b' traduce carácter por carácter
-d 'X' borra los caracteres indicados
-s 'X' comprime repeticiones consecutivas en una
-c complemento: actúa sobre los no listados

Ya lo has visto en acción: tr -s ' ' resuelve el problema de cut del apartado anterior. Otros usos habituales: tr -d '\r' para limpiar ficheros que vienen de Windows —una fuente clásica de fallos incomprensibles— y tr -cd '[:print:]\n' para eliminar caracteres de control de un volcado.

  1. sort: ordenar de verdad

Opción Efecto
-n numérico
-h numérico con sufijos humanos (4K, 2M, 1G)
-V por número de versión (3.2.1 antes que 3.10.0)
-r invertido
-u elimina duplicados
-f ignora mayúsculas
-t';' delimitador de campos
-k3,3 ordena por el campo 3
-o fichero escribe la salida (permite el mismo fichero de entrada)
-s estable: no reordena lo que ya estaba empatado

La sintaxis de -k es la que más se malinterpreta. -kN significa «desde el campo N hasta el final de la línea», no «por el campo N». Para ordenar solo por un campo hay que escribir -kN,N.

operador@srv-tramontana:~$ tail -n +2 /home/operador/datos/reservas.csv | sort -t';' -k6,6nr | head -3
1001;2026-07-03;mas-figueres;Nuria Bosch;4;520.00
1014;2026-08-02;mas-figueres;Jordi Camps;4;520.00
1007;2026-07-19;la-solana;Anna Serra;3;435.50

-t';' fija el separador, -k6,6nr ordena por el campo 6 de forma numérica e inversa. Los modificadores n y r se pegan al -k para que se apliquen solo a ese campo; puestos sueltos afectarían a toda la línea.

-V es específico y muy útil en nuestro caso: ls /opt/tramontana/releases/ | sort -V ordena 3.1.0, 3.2.0, 3.2.1, 3.3.0 correctamente, mientras que un sort normal pondría 3.10.0 antes que 3.2.0.

Recuerda de 03-01 que el resultado de sort depende de la locale. Cuando la salida vaya a compararse o versionarse, LC_ALL=C sort.

  1. uniq: contar apariciones

Opción Efecto
-c prefija cada línea con su número de repeticiones
-d solo las líneas duplicadas
-u solo las que aparecen una vez
-i ignora mayúsculas
-f N ignora los N primeros campos al comparar

uniq solo compara líneas adyacentes. No es un defecto: es lo que le permite procesar ficheros enormes sin memoria. La consecuencia es que exige entrada ordenada.

operador@srv-tramontana:~$ printf 'a\nb\na\n' | uniq -c | tr '\n' ' '
      1 a       1 b       1 a
operador@srv-tramontana:~$ printf 'a\nb\na\n' | sort | uniq -c | tr '\n' ' '
      2 a       1 b

De ahí el caballo de batalla del análisis de logs, que ya usaste sin explicación:

sort | uniq -c | sort -rn

Agrupa lo igual, cuenta cada grupo y ordena por frecuencia descendente. Es la respuesta a cualquier pregunta de la forma «¿qué es lo que más se repite?».

  1. paste, join y comm: comparar listados

paste pega ficheros lado a lado (paste -d';' a.txt b.txt). join hace una unión relacional por un campo común y exige ambos ficheros ordenados por él. comm compara dos ficheros ordenados y produce tres columnas: solo en el primero, solo en el segundo, en ambos.

operador@srv-tramontana:~$ cut -d';' -f3 /home/operador/datos/reservas.csv | tail -n +2 | sort -u > /tmp/con-reservas.txt
operador@srv-tramontana:~$ comm -23 <(sort /home/operador/datos/casas.txt) /tmp/con-reservas.txt

Sin salida: las cinco casas del catálogo tienen al menos una reserva. -23 suprime las columnas 2 y 3 y deja solo «en el catálogo pero sin reservas», que es exactamente la pregunta. <(...) es una sustitución de proceso: Bash entrega la salida de ese comando como si fuera un fichero, lo que evita crear temporales.

  1. sed: el editor de flujo

sed lee la entrada línea a línea, y para cada una ejecuta los comandos que le has dado y, salvo que digas lo contrario, la imprime. Ese ciclo lo explica todo: sed no carga el fichero en memoria, por eso procesa ficheros de gigabytes.

Direcciones

Dirección Selecciona
5 la línea 5
2,10 de la 2 a la 10
$ la última
/regex/ las que casan
/inicio/,/fin/ desde una hasta otra
2~3 la 2 y luego cada 3
/regex/! las que no casan

El comando s

s/patrón/reemplazo/banderas, con estas banderas:

Bandera Efecto
g todas las ocurrencias de la línea, no solo la primera
i ignora mayúsculas
p imprime la línea modificada (útil con -n)
3 solo la tercera ocurrencia
w f escribe las líneas modificadas en f

El delimitador no tiene por qué ser /: cualquier carácter vale, y usar otro evita la «valla de barras» cuando el patrón contiene rutas.

operador@srv-tramontana:~$ echo '/opt/tramontana/releases/3.2.1' | sed 's|/opt/tramontana|/srv/app|'
/srv/app/releases/3.2.1

Los grupos de captura funcionan como en las regex, \1, \2… los reutilizan en el reemplazo y & representa todo lo casado. Con -E no hay que escapar paréntesis ni llaves:

operador@srv-tramontana:~$ echo '1001;2026-07-03;mas-figueres' | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
1001;03/07/2026;mas-figueres

Otros comandos

Comando Hace
d borra (no imprime) la línea
p imprime; combínalo con -n
a texto / i texto añade después / inserta antes
c texto reemplaza la línea entera
y/abc/xyz/ traduce carácter a carácter, como tr
q sale (con sed '100q' cortas en la línea 100)
operador@srv-tramontana:~$ sed -e '1d' -e 's/;/ | /g' /home/operador/datos/reservas.csv | head -1
1001 | 2026-07-03 | mas-figueres | Nuria Bosch | 4 | 520.00

Con -n, sed no imprime nada por su cuenta y solo sale lo que p selecciona: sed -n '/ERROR 500/p' errores.log devuelve las 41 líneas de error, es decir, sed imitando a grep. Varios comandos se encadenan con -e repetido o separándolos con ;.

Edición en sitio: por qué -i.bak es obligatorio

sed -i modifica el fichero directamente. En producción, nunca sin sufijo.

operador@srv-tramontana:~$ sudo sed -i.bak-$(date +%F) 's/^log_nivel=debug$/log_nivel=info/' /etc/tramontana/app.conf
operador@srv-tramontana:~$ sudo diff -u /etc/tramontana/app.conf.bak-2026-08-18 /etc/tramontana/app.conf
@@ -6,2 +6,2 @@
-log_nivel=debug
+log_nivel=info

Con -i.bak-$(date +%F), sed guarda el original con ese sufijo antes de escribir. Sin él, si el patrón estaba mal —y un patrón mal escrito puede vaciar medio fichero sin avisar— no hay vuelta atrás: sed no pregunta, no avisa y no deshace. La convención de copia previa del curso y esta opción son lo mismo, integrado en un solo comando. Fíjate además en las anclas ^ y $: sin ellas, el patrón casaría también dentro de un comentario.

El procedimiento correcto es siempre en dos pasos: ejecutar sed sin -i para ver el resultado en pantalla, y solo entonces añadir -i.bak-....

  1. awk: el lenguaje de los campos

awk es un lenguaje de programación completo disfrazado de comando. Su modelo es:

awk 'patrón { acción }' fichero

Para cada línea, si el patrón se cumple, ejecuta la acción. Sin patrón, se aplica a todas; sin acción, imprime la línea.

Campos y variables

Variable Contiene
$0 la línea entera
$1, $2… $NF los campos; $NF es el último
NF número de campos de la línea
NR número de línea
FS / OFS separador de entrada / de salida
FILENAME nombre del fichero actual

Por defecto FS es «cualquier bloque de espacios o tabuladores», que es justo lo que cut no sabe hacer:

operador@srv-tramontana:~$ awk '{print $3, $4}' /var/log/tramontana/acceso.log | head -2
GET /reservas/1012
POST /reservas

Para CSV se cambia con -F';'. Los bloques BEGIN y END se ejecutan antes de la primera línea y después de la última:

operador@srv-tramontana:~$ awk -F';' 'NR>1 {n++; s+=$6} END {printf "%d reservas, %.2f EUR, media %.2f\n", n, s, s/n}' \
    /home/operador/datos/reservas.csv
25 reservas, 7842.50 EUR, media 313.70

NR>1 salta la cabecera —un patrón sin llaves es una condición—, las variables se crean solas con valor 0, y printf da formato: %d entero, %.2f decimal con dos cifras.

Condiciones y arrays asociativos

awk -F';' '$5 >= 5 {print $1, $3, $5}' reservas.csv devuelve las tres estancias de cinco noches o más. Y ahora la característica que hace de awk algo distinto: los arrays asociativos, que permiten agrupar y sumar en una sola pasada.

operador@srv-tramontana:~$ awk -F';' 'NR>1 {total[$3]+=$6} END {for (c in total) printf "%-14s %8.2f\n", c, total[c]}' \
    /home/operador/datos/reservas.csv | sort -k2 -nr
mas-figueres    2450.00
can-ventos      1980.00
la-solana       1425.50
cal-ferrer      1120.00
el-moli          867.00

total[$3]+=$6 usa el nombre de la casa como índice: no hay que declarar nada ni saber de antemano cuántas casas hay. El bucle for (c in total) recorre las claves —en orden impredecible, de ahí el sort final— y %-14s alinea a la izquierda en 14 caracteres.

Por qué awk sustituye a media tubería: ese comando hace en una pasada lo que exigiría cut | sort | uniq más una suma que ninguna de las tres sabe hacer. Cuando necesites agrupar y calcular a la vez, awk no es una opción entre otras: es la única del conjunto que puede.

  1. Tabla de decisión: qué herramienta y cuándo

Necesito Herramienta
Recortar campos con delimitador fijo cut
Recortar campos separados por espacios variables awk '{print $N}'
Cambiar o borrar caracteres sueltos tr
Filtrar líneas por un patrón grep
Sustituir texto en muchas líneas sed
Ordenar, deduplicar, contar frecuencias sort + uniq -c
Sumar, promediar, agrupar por clave awk
Condiciones sobre varios campos a la vez awk
Varios ficheros, JSON, estado complejo, más de 20 líneas Python

La última fila es un consejo profesional, no una rendición. Una tubería de seis eslabones con dos sed anidados es más difícil de mantener que quince líneas de Python legible. El punto de corte razonable: si no cabe en una pantalla o si tienes que dibujarla para entenderla, cambia de herramienta. Y para JSON, ni lo intentes con sed: existe jq.

  1. Caso A: informe de facturación para Marta

El encargo: total facturado, media de noches e importe por casa del periodo cargado en reservas.csv. Se construye por pasos, verificando.

Verificación previa con awk -F';' 'NR>1 {n++} END {print n, NF}': 25 registros y 6 campos. Si alguna línea no tuviera 6 campos, cualquier suma posterior estaría mal; la validación de 03-02 ya nos dijo que el formato es correcto.

operador@srv-tramontana:~$ awk -F';' '
  NR>1 { res[$3]++; noc[$3]+=$5; imp[$3]+=$6; tn+=$5; ti+=$6; tr_++ }
  END {
    printf "%-14s %5s %7s %10s\n", "CASA", "RES", "NOCHES", "IMPORTE"
    for (c in res) printf "%-14s %5d %7d %10.2f\n", c, res[c], noc[c], imp[c]
    printf "%-14s %5d %7d %10.2f\n", "TOTAL", tr_, tn, ti
    printf "Media de noches por reserva: %.2f\n", tn/tr_
  }' /home/operador/datos/reservas.csv
CASA             RES  NOCHES    IMPORTE
mas-figueres       7      21    2450.00
can-ventos         6      17    1980.00
la-solana          5      13    1425.50
cal-ferrer         4      11    1120.00
el-moli            3       8     867.00
TOTAL             25      70    7842.50
Media de noches por reserva: 2.80

Tres arrays asociativos indexados por la misma clave, tres acumuladores globales y un END que formatea. El programa awk va entre comillas simples y puede ocupar varias líneas: Bash no toca nada de lo que hay dentro. Nótese que la variable se llama tr_ y no tr: dentro de awk no hay conflicto con el comando, pero evitar nombres que coinciden con comandos ahorra confusión al releerlo.

Comprobación final imprescindible: 7+6+5+4+3 = 25 reservas y las sumas parciales dan el total. Un informe cuyo desglose no cuadra con el total no se entrega.

  1. Caso B y C: rutas con errores e IPs anómalas

B) Rutas con más errores. Ampliamos la tubería de 03-04 a todos los códigos 4xx y 5xx:

operador@srv-tramontana:~$ awk '$5 ~ /^[45][0-9][0-9]$/ {print $5, $4}' /var/log/tramontana/acceso.log \
    | sort | uniq -c | sort -rn | head -10
      9 500 /reservas
      5 503 /reservas/pago
      4 500 /reservas/pago
      4 404 /casas/el-molí
      1 500 /casas

Cinco combinaciones, no diez: el listado es corto porque el log lo es. Suman 23, y los 500 suman 14, que es exactamente lo que contamos en 03-04. $5 ~ /regex/ es la comparación por patrón de awk, aplicada solo al campo del código de estado, lo que evita el problema que en 03-02 resolvíamos rodeando el patrón de espacios. Y hay un hallazgo lateral: los cuatro 404 de /casas/el-molí llevan tilde, mientras que en el catálogo la casa es el-moli. Alguien está generando enlaces con el nombre acentuado. No es un fallo del servidor: es un fallo de la aplicación, y hay que decírselo a Luis.

C) IPs con más peticiones.

operador@srv-tramontana:~$ awk -F'ip=' '{split($2, a, " "); c[a[1]]++} END {for (i in c) print c[i], i}' \
    /var/log/tramontana/acceso.log | sort -rn | head -5
138 10.0.2.77
94 10.0.2.31
61 10.0.2.44
38 10.0.2.52
27 10.0.2.18

-F'ip=' parte cada línea por esa cadena, y split($2, a, " ") corta el resto por el primer espacio para quedarse con la IP. Es una forma de extraer un campo con nombre sin depender de su posición.

La lectura del dato es lo importante. 10.0.2.77 acumula 138 de 412 peticiones —el 33 %— frente a las 94 de la segunda. ¿Es un ataque? Todavía no lo sabemos, y decir que sí sería precipitado. Miramos qué hace:

operador@srv-tramontana:~$ grep 'ip=10.0.2.77' /var/log/tramontana/acceso.log \
    | awk '{print $3, $4, $5}' | sort | uniq -c | sort -rn | head -3
    124 GET /reservas 200
      9 GET /reservas 500
      5 POST /reservas/pago 503

Un patrón uniforme, casi todo GET /reservas con éxito y a ritmo constante: se parece más a un sistema automatizado —un monitor, un rastreador, una integración— que a una persona. El informe para Marta debe decir eso y no más: hay una IP que concentra un tercio del tráfico con un patrón automatizado; los datos disponibles no permiten distinguir un servicio legítimo de un abuso; hay que identificar de quién es esa dirección antes de tomar ninguna medida. Distinguir lo que los datos demuestran de lo que sugieren es parte del trabajo.

Errores Comunes y Consejos

  • uniq -c sin sort delante. Solo agrupa líneas adyacentes; el recuento saldrá fragmentado y parecerá correcto.
  • sort -k3 esperando ordenar por el campo 3. Ordena desde el 3 hasta el final. Escribe -k3,3.
  • cut -d' ' sobre salida alineada. Los espacios repetidos crean campos vacíos. Usa tr -s ' ' o awk.
  • sed -i sin sufijo de copia. No hay deshacer. Siempre -i.bak-$(date +%F), y prueba antes sin -i.
  • Olvidar NR>1 en un CSV con cabecera. En awk una cadena vale 0, así que no da error: falsea el recuento en silencio.
  • Entrecomillar un programa de awk con comillas dobles. Bash expandirá $1. Comillas simples siempre.
  • Comparar números como texto. sort sin -n pone 100 antes que 20. Y ordena primero, formatea después: el relleno de printf desalinea los campos de sort.
  • Consejo: deja un wc -l al final mientras construyes una tubería; si el número cambia donde no esperabas, ahí está el error. Y recuerda que awk acepta varios ficheros: FILENAME dice cuál procesa y FNR es el número de línea dentro de ese fichero, frente a NR, que es global.

Ejercicios

Ejercicio 1. Genera un listado de las casas ordenado por importe medio por noche (importe total dividido entre noches totales), de mayor a menor, con dos decimales. Explica por qué no basta con dividir la media de importes entre la media de noches.

Ejercicio 2. El fichero /etc/tramontana/app.conf tiene max_conexiones=200 y timeout_consulta=30. Súbelos a 400 y 60 respectivamente en un solo comando, con copia previa y verificación, y explica cada elemento del patrón que uses.

Ejercicio 3. Marta pregunta qué porcentaje de las peticiones de acceso.log terminó en error (4xx o 5xx) y en qué franja horaria se concentran. Responde con una sola tubería para cada pregunta y redacta la conclusión en dos frases.

Soluciones

Solución 1.

Un primer intento con printf "%-14s %7.2f\n", c, imp[c]/noc[c] y sort -k2 -nr sale desordenado: -k2 significa «desde el campo 2 hasta el final», y como %-14s rellena con espacios, el campo 2 no empieza donde sort cree. La corrección:

operador@srv-tramontana:~$ awk -F';' 'NR>1 {noc[$3]+=$5; imp[$3]+=$6}
  END {for (c in noc) printf "%.2f %s\n", imp[c]/noc[c], c}' \
  /home/operador/datos/reservas.csv | sort -rn
116.67 mas-figueres
116.47 can-ventos
109.65 la-solana
108.38 el-moli
101.82 cal-ferrer

Poniendo el número primero y sin relleno, sort -rn funciona sin ambigüedad. Es una técnica que conviene adoptar: ordena primero, formatea después.

Sobre la pregunta: no basta con dividir medias porque la media de cocientes no es el cociente de medias. Una reserva de 7 noches pesa mucho más en el total de noches que una de 2, y dividir promedios trata a ambas por igual. El cálculo correcto es el que hemos hecho, sumando importes y noches por separado y dividiendo los totales.

Solución 2.

operador@srv-tramontana:~$ sudo sed -E 's/^(max_conexiones)=200$/\1=400/; s/^(timeout_consulta)=30$/\1=60/' \
    /etc/tramontana/app.conf | grep -E 'max_conexiones|timeout_consulta'
max_conexiones=400
timeout_consulta=60
operador@srv-tramontana:~$ sudo sed -i.bak-$(date +%F) -E \
    's/^(max_conexiones)=200$/\1=400/; s/^(timeout_consulta)=30$/\1=60/' /etc/tramontana/app.conf
operador@srv-tramontana:~$ sudo diff -u /etc/tramontana/app.conf.bak-2026-08-18 /etc/tramontana/app.conf
@@ -4,2 +4,2 @@
-max_conexiones=200
-timeout_consulta=30
+max_conexiones=400
+timeout_consulta=60

Cada elemento: -E para no escapar los paréntesis; ^ y $ para que el patrón case la línea entera y no un fragmento dentro de un comentario; el grupo (clave) y su \1 para no repetir el nombre en el reemplazo, lo que evita erratas; el valor antiguo en el patrón, que actúa como comprobación —si el fichero ya tuviera otro valor, la sustitución no se aplicaría en vez de pisarlo a ciegas—; ; para encadenar dos sustituciones en un solo comando; y -i.bak-$(date +%F) para la copia. El primer comando, sin -i, es la prueba en seco: solo cuando su salida es la esperada se ejecuta el segundo.

Solución 3.

operador@srv-tramontana:~$ awk '$5 ~ /^[45]/ {e++} END {printf "%d de %d peticiones: %.1f%%\n", e, NR, 100*e/NR}' \
    /var/log/tramontana/acceso.log
23 de 412 peticiones: 5.6%
operador@srv-tramontana:~$ awk '$5 ~ /^[45]/ {print substr($2,1,2)":00"}' /var/log/tramontana/acceso.log \
    | sort | uniq -c | sort -rn | head -4
     15 03:00
      4 11:00
      2 09:00
      2 17:00

substr($2,1,2) toma los dos primeros caracteres del campo de la hora. %% imprime un porcentaje literal en printf.

El 5,6 % de las 412 peticiones registradas terminó en error, una proporción que por sí sola no es alarmante. Sin embargo, 15 de los 23 errores —casi dos tercios— se concentran en la franja de las 03:00, lo que apunta a un problema puntual durante la ventana nocturna y no a una degradación general del servicio.

Esa concentración encaja con lo que veníamos viendo: los db_timeout de errores.log, el timeout_consulta=30 agotado y las conexiones_activas=200 en el límite configurado. Todo señala a la tarea nocturna que compite por las conexiones de la base de datos con las peticiones de los usuarios.

Conclusión

Has convertido dos ficheros de texto en informes defendibles, y de paso has cerrado el círculo que abrió la filosofía Unix del Módulo 1: el texto plano como interfaz universal entre programas que no se conocen.

  • cut recorta por delimitador fijo, con su límite ante delimitadores repetidos; tr traduce, borra y comprime caracteres.
  • sort ordena por campo con la sintaxis real -kN,N, con -n, -h, -V, -u y -o; uniq -c cuenta y exige entrada ordenada, y el patrón sort | uniq -c | sort -rn responde a cualquier pregunta de frecuencia.
  • Conoces paste, join y comm para comparar listados, y la sustitución de proceso <(...) para no crear temporales.
  • sed procesa línea a línea; manejas direcciones, el comando s con sus banderas y delimitadores alternativos, d, p con -n, los grupos de captura, y sabes que -i.bak-$(date +%F) no es opcional y que antes va siempre la prueba sin -i.
  • awk te da patrón { acción }, los campos $1…$NF, NR, NF, FS, BEGIN/END, printf y los arrays asociativos que agrupan y suman en una pasada, sustituyendo a media tubería.
  • Tienes una tabla de decisión y un criterio para saber cuándo toca pasar a Python.
  • Y has producido tres informes reales: la facturación por casa con su desglose cuadrado, las rutas con más errores —descubriendo de paso un fallo de la aplicación con la tilde de el-molí— y la IP que concentra un tercio del tráfico, con la honestidad de decir qué demuestran los datos y qué solo sugieren.

Hasta aquí has trabajado con archivos. La siguiente lección cambia de objeto: Gestión de Procesos se ocupa de los programas en ejecución. Verás qué es un PID y cómo se organiza el árbol de procesos desde systemd, cómo leer ps aux y top columna a columna —incluido qué significan de verdad los tres números del load average—, qué señales existen y por qué un profesional intenta SIGTERM y espera antes de recurrir a kill -9, y cómo averiguar con lsof qué proceso tiene ocupado un puerto o un fichero. El caso práctico te esperará ya planteado: la aplicación de Tramontana se queda colgada de madrugada, justo en esa franja de las 03:00 que acabas de identificar, y hay que diagnosticarla y reiniciarla sin perder las peticiones en curso.

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados