Tabla de contenido
Una vez más aquí. Como me han jodido las vacaciones, por contratar unos albañiles que no hacen puente, y me he tenido que quedar en casa debajo del aire acondicionado haciendo algunas cosas que me han pedido. Terminadas las más importantes, me he puesto con este pequeño script en Bash para gestionar citas desde la terminal. Este código me lo ha pedido el profesor del curso que estoy haciendo, y aun que en principio lo hice con un menú y sus cosas, descubrí al terminar que me había equivocado. El objetivo de este ejercicio creo que era el pasar parámetros desde la terminal y que el script los procesara para hacer una u otra cosa. Por este motivo, tuve que volver a empezar. Y una vez terminado, pues aquí lo voy a dejar publicado, por si a alguien le sirve para lo que sea.
El script Bash para gestionar citas que a continuación vamos a ver, permite añadir, eliminar, buscar y listar citas de «supuestos» pacientes. Su funcionalidad se basa en el procesamiento de los datos que se van a guardar y a leer desde un archivo de texto llamado citas.txt
. El script se basa en el lenguaje de programación de shell Bash y utiliza diversas funciones y comandos para llevar a cabo las tareas de administración de citas.
Requisitos que debe cumplir este script Bash
Como decía líneas más arriba. Esto es algo que me han pedido, y que debe cumplir ciertos requisitos, que vamos a ver a continuación:
- Vamos a crear un script en Bsh que llamaremos citas.sh, el cual nos permitirá utilizar las siguientes opciones a la hora de llamarlo desde la terminal:
-h ó –help -> para mostrar la ayuda
-a ó –add -> para añadir una cita siguiendo el formato HORA_INICIO, HORA_FIN, NOMBRE_PACIENTE.
-d ó –delete -> para eliminar una cita introduciendo el nombre del paciente.
-s ó –search -> para buscar los pacientes que contengan un patrón determinado (el nombre del paciente)
-i ó –init -> para buscar los pacientes que empiecen a una HORA_INICIO determinada.
-e ó –end -> para buscar los pacientes que terminen a una HORA_FIN determinada.
-n ó –name -> para listar todas las citas ordenadas por NOMBRE_PACIENTE.
-o ó –hour -> para listar las citas ordenadas por HORA_INICIO.
- Para cada operación se comprobará si se introducen el números de parámetros correcto y en el formato correcto.
- Se debe comprobar que la hora de inicio sea anterior a la hora de fin de la cita.
- Los datos se deben guardar en un archivo llamado citas.txt
- HORA_INICIO y HORA_FIN son números entre 00 y 23.
- Al introducir una cita se comprobará que no se solape con otra cita ya introducida.
- No debemos admitir nombres de usuarios repetidos
El programa citas.sh nos debe permitir a través de estas opciones descritas, añadir una cita nueva, eliminar una cita, buscar por nombre del paciente, buscar citas por la hora de inicio, buscar por la hora de fin de la cita, listar citas ordenadas por el nombre de paciente o listar por la hora de inicio de la cita. Todo ello desde la terminal.
Y bueno, con todo esto, continuamos creando el código …
Una breve explicación del código de este script Bash para gestion de citas
Para empezar decir que vamos a declarar algunos colores. En el inicio del script, se definen códigos de escape ANSI para colores y estilos de texto que se utilizan para resaltar información en la terminal. Estos códigos permiten resaltar mensajes importantes con colores como verde, rojo y amarillo para mejorar la legibilidad y el impacto visual.

En el código vamos a crear una función llamada show_help
. Esta función muestra la ayuda cuando se utiliza la opción -h
o --help
a la hora de llamar al script. Esta función va a imprimir información detallada sobre cómo usar el script y las diferentes opciones disponibles.
También vamos a crear una función para la validación de las horas de las citas. Esta función llamada validar_hora
verifica si el formato de hora proporcionado es válido (HH:MM) y si está dentro del rango de 00:00 a 23:59. Se utilizan expresiones regulares para realizar estas validaciones.
La función cabecera
imprime una línea de encabezado resaltada con el color verde para separar y marcar las diferentes secciones del script.

También crearemos una función add_cita
. Esta función se encarga de añadir citas. Realiza varias validaciones, como verificar si se proporcionaron suficientes argumentos, si las horas están en el formato correcto y si hay solapamiento con otras citas existentes. Si todo se cumple, se añade la cita al archivo citas.txt
.

Otras función que es necesario crear, será la función buscar citas que coincidan con un nombre de paciente proporcionado, mostrando los resultados en la terminal. Utilizaremos el comando grep
para buscar en el archivo citas.txt
.

Aun que en las exigencias del profesor no estaba la posibilidad de eliminar citas, creo que en un programa en el que se pueden guardar citas, es imprescindible que se se puedan eliminar. Por este motivo, añadí la función eliminar cita, con la que se puede eliminar una cita guardada en el archivo citas.txt escribiendo el nombre del usuario que tiene la cita.
Con las funciones buscar_por_hora_inicio
y buscar_por_hora_finalizacion
, los usuarios podrán buscar citas que comiencen o terminen en una hora específica proporcionada. Estas realizarán validaciones de formato y utilizan el comando grep
para buscar coincidencias en el archivo citas.txt
.

Las funciones listar_por_nombre
y listar_por_hora
muestran las citas almacenadas en el archivo citas.txt
, ordenadas por nombre o por hora de inicio, respectivamente. Vamosa a utilizar el comando sort
para ordenar las citas antes de mostrarlas.
Todas estas opciones se manejan desde un bucle case. El script utiliza este bucle para manejar las diferentes opciones proporcionadas en la línea de comandos. Dependiendo de la opción elegida (como -a
, -d
, -s
, etc.), se llama a la función correspondiente para realizar la acción requerida.
En resumen, el script Bash utiliza una combinación de comandos de terminal, expresiones regulares y funciones personalizadas para administrar citas. Las funciones de validación, búsqueda y manipulación de archivos son fundamentales para lograr la funcionalidad del script y proporcionar una interfaz de usuario interactiva para la gestión de los datos.
El código del script Bash
Todo el código del script, en el que se muestran todas las funcionalidades descritas líneas más arriba, se ven funcionando en el siguiente código:
#!/bin/bash # Colores verde="\033[1;32m" cierreVerde="\033[0m" rojo="\033[1;31m" cierreRojo="\033[0m" amarillo="\033[1;33m" cierreAmarillo="\033[0m" # Función para mostrar la ayuda show_help() { cabecera " AYUDA" echo "" echo -e "${amarillo}Uso: ./citas.sh [opciones]${cierreAmarillo}" echo "Opciones:" echo " -h, --help Mostrar esta ayuda" echo " -a, --add Añadir una cita con HORA_INICIO, HORA_FIN y NOMBRE_PACIENTE (10:00 11:00 NombrePaciente)." echo " -d, --delete Borrar una cita de un paciente. Sin argumentos." echo " -s, --search Buscar pacientes por el nombre." echo " -i, --init Buscar pacientes que empiecen a una HORA_INICIO determinada." echo " -e, --end Buscar pacientes que terminen a una HORA_FIN determinada." echo " -n, --name Listar todas las citas ordenadas por NOMBRE_PACIENTE. Sin argumentos." echo " -o, --hour Listar todas las citas ordenadas por HORA_INICIO. Sin argumentos." echo "" exit 0 } # Función para validar el formato de hora (HH:MM) validar_hora() { if [[ "$1" =~ ^([01]?[0-9]|2[0-3]):[0-5][0-9]$ ]]; then return 0 else return 1 fi } # Función para generar la cabecera personalizada según la orden que reciba function cabecera() { echo -e "${verde}===============================" echo " $1" echo "===============================" echo -e "${cierreVerde}" } # Función para añadir citas. Comprobación parámetros, existencia archivo citas.txt, formato de horas, solapamiento citas, comprobación de si ya hay una cita # para el usuario add_cita() { cabecera " Añadir citas" if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then echo -e "${rojo}Faltan parámetros. Uso: add_cita HORA_INICIO HORA_FIN NOMBRE_PACIENTE${cierreRojo}" exit 1 fi if [ ! -e citas.txt ]; then touch citas.txt echo -e "${verde}Se ha creado la BD en el archivo citas.txt${cierreVerde}" fi if ! validar_hora "$1" || ! validar_hora "$2"; then echo -e "${rojo}Las horas deben estar en el formato correcto (HH:MM) y en el rango de 00:00 a 23:59.${cierreRojo}" exit 1 fi if [[ "$1" < "$2" ]]; then solapamiento=false while IFS=',' read -r inicio_existente fin_existente _; do # Calcula los minutos correspondientes a las horas y minutos de inicio y fin de la cita existente inicio_existente_minutos=$(( 10#$(date -d "$inicio_existente" +%H) * 60 + 10#$(date -d "$inicio_existente" +%M) )) fin_existente_minutos=$(( 10#$(date -d "$fin_existente" +%H) * 60 + 10#$(date -d "$fin_existente" +%M) )) # Calcula los minutos correspondientes a las horas y minutos de inicio y fin de la nueva cita nuevo_inicio_minutos=$(( 10#$(date -d "$1" +%H) * 60 + 10#$(date -d "$1" +%M) )) nuevo_fin_minutos=$(( 10#$(date -d "$2" +%H) * 60 + 10#$(date -d "$2" +%M) )) # Verifica si hay solapamiento entre las citas if (( nuevo_inicio_minutos >= inicio_existente_minutos && nuevo_inicio_minutos < fin_existente_minutos )) || \ (( nuevo_fin_minutos > inicio_existente_minutos && nuevo_fin_minutos <= fin_existente_minutos )) || \ (( inicio_existente_minutos >= nuevo_inicio_minutos && inicio_existente_minutos < nuevo_fin_minutos )) || \ (( fin_existente_minutos > nuevo_inicio_minutos && fin_existente_minutos <= nuevo_fin_minutos )); then solapamiento=true break fi done < citas.txt if $solapamiento; then echo -e "${rojo}La cita se solapa con otra cita existente.${cierreRojo}" else if grep -q "$3" citas.txt; then echo -e "${rojo}Ya existe una cita para el paciente $3.${cierreRojo}" else echo "$1,$2,$3" >> citas.txt echo -e "${verde}Cita para $3 añadida de forma correcta. Hora de inicio: $1. Hora de fin: $2${cierreVerde}" fi fi else echo -e "${rojo}La hora de inicio debe ser anterior a la hora de fin.${cierreRojo}" fi } eliminar_cita() { cabecera " Eliminar una cita" if [ -e citas.txt ]; then read -p "Escribe el nombre del paciente para eliminar su cita: " nombre_paciente if [ -z "$nombre_paciente" ]; then echo "" echo -e "${rojo}El nombre del paciente no puede estar vacío.${cierreRojo}" return fi if grep -q "$nombre_paciente" citas.txt; then echo "" echo "Se encontró una cita para el paciente $nombre_paciente:" grep "$nombre_paciente" citas.txt echo "" echo -e "${rojo}" read -p "¿Estás seguro de que quieres eliminar esta cita? (s/n): " confirmacion echo -e "${cierreRojo}" if [ "$confirmacion" = "s" ]; then grep -v "$nombre_paciente" citas.txt > citas_tmp.txt mv citas_tmp.txt citas.txt echo -e "${verde}Cita para el paciente $nombre_paciente eliminada.${cierreVerde}" else echo "" echo -e "${amarillo}Eliminación cancelada.${cierreAmarillo}" fi else echo "" echo -e "${amarillo}No se encontró ninguna cita para el paciente $nombre_paciente.${cierreAmarillo}" fi else echo "" echo -e "${rojo}El archivo citas.txt no existe. Primero añade registros de citas.${cierreRojo}" fi } # Función para buscar por nombre buscar_por_nombre() { cabecera " Búsqueda por nombre" if [ -z "$1" ]; then echo "" echo -e "${rojo}Falta la opción del nombre del paciente.${cierreRojo}" elif [ -e citas.txt ]; then resultados=$(grep -i ",.*$1" citas.txt) if [ -n "$resultados" ]; then echo "$resultados" | while IFS=',' read -r inicio fin paciente; do echo -e "-> ${verde}Paciente: $paciente ${cierreVerde}- Hora inicio: $inicio - Hora fin: $fin" done else echo "" echo -e "${amarillo}No se encontraron pacientes con el nombre '$1'.${cierreAmarillo}" fi else echo "" echo -e "${rojo}El archivo citas.txt no existe.${cierreRojo}" fi } # Función para buscar pacientes que empiecen a una hora determinada buscar_por_hora_inicio() { cabecera "Búsqueda por hora de inicio" if [ -z "$1" ]; then echo -e "${rojo}Falta la opción de la hora de inicio.${cierreRojo}" exit 1 elif ! validar_hora "$1"; then echo -e "${rojo}La hora de inicio debe estar en el formato correcto (HH:MM) y en el rango de 00:00 a 23:59.${cierreRojo}" exit 1 elif [ -e citas.txt ]; then resultados=$(grep "^$1," citas.txt) if [ -n "$resultados" ]; then echo "Pacientes con cita que empiezan a la hora '$1':" echo "$resultados" | while IFS=',' read -r inicio fin paciente; do echo -e "-> Paciente: $paciente - ${verde}Hora inicio: $inicio ${cierreVerde}- Hora fin: $fin" done else echo -e "${amarillo}No se encontraron pacientes con cita que empiecen a la hora '$1'.${cierreAmarillo}" fi else echo -e "${rojo}El archivo citas.txt no existe.${cierreRojo}" exit 1 fi } # Función para buscar pacientes que terminen a una hora determinada buscar_por_hora_finalizacion() { cabecera "Búsqueda por hora de finalización" if [ -z "$1" ]; then echo -e "${rojo}Falta la opción de la hora de finalización.${cierreRojo}" exit 1 elif ! validar_hora "$1"; then echo -e "${rojo}La hora de finalización debe estar en el formato correcto (HH:MM) y en el rango de 00:00 a 23:59.${cierreRojo}" exit 1 fi if [ -e citas.txt ]; then resultados=$(grep ",$1" citas.txt) if [ -n "$resultados" ]; then echo "Pacientes con cita que terminan a la hora '$1':" echo "$resultados" | while IFS=',' read -r inicio fin paciente; do echo -e "-> Paciente: $paciente - Hora inicio: $inicio - ${verde}Hora fin: $fin ${cierreVerde}" done else echo -e "${rojo}No se encontraron pacientes con cita que terminen a la hora '$1'.${cierreRojo}" fi else echo -e "${rojo}El archivo citas.txt no existe.${cierreRojo}" exit 1 fi } # Función para listar citas ordenadas por nombre listar_por_nombre() { cabecera "Listado ordenado por nombre" # -k3 ordena vía key posición3 sort -t',' -k3 citas.txt | while IFS=',' read -r hora_inicio hora_fin paciente; do echo -e "Paciente: ${verde}$paciente ${cierreVerde}- Hora inicio: $hora_inicio - Hora fin: $hora_fin" done } # Función para listar citas ordenadas por hora de inicio listar_por_hora() { cabecera "Ordenado por hora de inicio" sort -t',' -k1 citas.txt | while IFS=',' read -r hora_inicio hora_fin paciente; do echo -e "Paciente: $paciente - Hora inicio: ${verde}$hora_inicio ${cierreVerde}- Hora fin: $hora_fin" done } # Menejo de opciones disponibles case "$1" in -h|--help) show_help ;; -a|--add) shift add_cita "$1" "$2" "$3" ;; -d|--delete) eliminar_cita ;; -s|--search) shift buscar_por_nombre "$1" ;; -i|--init) shift buscar_por_hora_inicio "$1" ;; -e|--end) shift buscar_por_hora_finalizacion "$1" ;; -n|--name) listar_por_nombre ;; -o|--hour) listar_por_hora ;; *) echo "Opción inválida. Utiliza -h o --help para ver la ayuda." exit 1 ;; esac
El script Bash para gestionar citas que aquí se puede ver, es una opción sencilla y sin muchas pretensiones para guardar datos dentro de un archivo .txt, utilizando la automatización de algunos procesos. Con su interfaz y diversas funciones, es posible agregar, eliminar, buscar y listar citas de manera sencilla y ordenada. El uso de un archivo de texto para almacenar los datos de las citas brinda flexibilidad y facilidad de acceso. Además, el script realiza verificaciones y validaciones para garantizar que las citas se añadan correctamente y se evite cualquier solapamiento.
Este código lo he subido (de forma automática) a GitHub, por lo que el código de este ejercicio también se puede encontrar publicado en su repositorio de GitHub.