Linux / Comando / basename: extraer el último componente de una ruta

basename es un comando que elimina la parte del directorio de una cadena de ruta y muestra solo el nombre del archivo o directorio final. Opcionalmente, también se puede eliminar el sufijo al final del nombre del archivo, lo que es útil cuando se desea convertir rutas a nombres para mostrar en scripts de shell.

basename no es un comando para abrir archivos ni para comprobar la existencia de rutas. Procesa la cadena de entrada, por lo que se puede usar incluso en rutas que no existen.

¿Qué es el comando basename?

Se usa basename cuando solo se necesita el último componente de una ruta.

basename /home/user/report.txt

La salida es la siguiente.

report.txt

No importa si la ruta de entrada es un archivo o un directorio. Después de limpiar la última barra, devuelve el último nombre.

Sintaxis y uso básico

basename NOMBRE [SUFIJO]
basename OPCIONES NOMBRE ...

El ejemplo de uso más básico es el siguiente.

basename /var/log/nginx/access.log
basename /home/user/Documents/
basename relative/path/file.txt

Cada resultado es access.log, Documents y file.txt. Las barras innecesarias al final de la ruta se eliminan, pero entradas especiales como la ruta raíz se manejan por separado.

Eliminar sufijos

Especificar el sufijo como segundo argumento

El segundo argumento elimina un sufijo literal coincidente al final del último componente, siempre que no sea idéntico al nombre completo. Por ejemplo, un sufijo .txt no convierte un archivo llamado exactamente .txt en un nombre vacío.

basename /data/archive.tar.gz .gz
basename /home/user/report.txt .txt

La salida será archive.tar y report, respectivamente. Para eliminar todo .tar.gz, especifique toda la cadena que desea eliminar.

basename /data/archive.tar.gz .tar.gz

Eliminar sufijos de varios nombres con -s

El -s o --suffix de GNU basename se especifica como sufijo en la opción. Al usar esta opción, también se activa el funcionamiento de -a que procesa varios nombres juntos.

basename -s .jpg /images/a.jpg /backup/b.jpg
basename --suffix=.log /var/log/app.log /tmp/test.log

Si el sufijo no coincide, se imprime tal cual el último nombre original. El sufijo se compara como cadena literal, no como expresión regular.

Procesar varias rutas

Imprimir varios nombres con -a

Al usar -a o --multiple, se pueden procesar varias rutas a la vez y se imprime cada resultado en una línea.

basename -a /srv/www/index.html /var/log/syslog /home/user

La salida tiene la siguiente forma.

index.html
syslog
user

Separar con caracteres NUL con -z

Los nombres de archivo pueden contener caracteres de salto de línea. Para evitar ambigüedades en la automatización, se puede imprimir un carácter NUL al final de cada resultado en lugar de un salto de línea usando -z o --zero.

basename -z -a /data/file1 /data/file2

Los siguientes comandos que reciben salida separada por NUL también deben admitir el mismo formato. No es una opción para ver directamente en la pantalla, sino una función para la transferencia segura entre programas.

Comparación entre basename y dirname

Entrada basename dirname
/home/user/report.txt report.txt /home/user
docs/manual.pdf manual.pdf docs
notes.txt notes.txt .
/ / /

Estos dos comandos son convenientes cuando se divide una cadena de ruta de manera complementaria. Sin embargo, si simplemente se vuelven a unir las dos salidas con una barra, puede que no coincida exactamente con la cadena original debido a barras duplicadas o entradas especiales.

Procesamiento de extensiones de archivos

Eliminar extensiones conocidas

Si la extensión a eliminar está determinada, es claro usar el argumento de sufijo.

basename photo.webp .webp
basename backup.tar.gz .tar.gz

Este método elimina solo cuando la parte final coincide exactamente, por lo que report.txt.bak no eliminará .txt.

No considerar automáticamente como extensión lo que está después del último punto

El hecho de que un nombre de archivo tenga un punto no significa que siempre tenga extensión. Hay archivos ocultos que comienzan con un punto como .profile, archivos con múltiples sufijos como archive.tar.gz, y nombres que terminan en punto.

De acuerdo con las reglas de trabajo, defina claramente qué sufijo eliminar y use con precaución la eliminación de todo lo que esté después del último punto.

Uso en scripts de shell

Obtener el nombre de archivo para mostrar desde la ruta

path='/srv/uploads/annual report.pdf'
name=$(basename -- "$path") || exit 1
printf 'Nombre de archivo: %s\n' "$name"

-- termina las opciones; el argumento siguiente puede comenzar por un guion. Las comillas dobles evitan la separación por espacios y la expansión de comodines. La sustitución $(...) elimina los saltos de línea finales de la salida: si necesita conservar nombres que terminen en salto de línea, utilice un flujo delimitado por NUL sin capturarlo de esta manera.

Comparación con la expansión de parámetros del shell POSIX

Si solo necesita la última parte de una ruta dentro del shell, también puede usar la expansión de parámetros en lugar de un comando externo.

path='/srv/uploads/report.pdf'
name=${path##*/}
printf '%s\n' "$name"

Sin embargo, si la ruta termina con una barra o es la ruta raíz, basename puede dar un resultado diferente. Si el formato de entrada no está controlado, no asuma que la regla de cadena que creó funciona de la misma manera que basename.

Resumen de opciones principales

Opciones Descripción
-a, --multiple Procesa varios nombres y muestra los resultados de cada uno.
-s SUFIJO, --suffix=SUFIJO Elimina el sufijo especificado al final de cada nombre y también habilita el procesamiento de varios nombres.
-z, --zero Finaliza cada resultado con un carácter NUL en lugar de un salto de línea.
--help Imprime el modo de uso y las opciones de soporte.
--version Imprime la versión de GNU Coreutils instalada.

Opciones como -a, -s, -z son extensiones de GNU. Si el script debe ejecutarse en varios sistemas tipo Unix, verifique la implementación en el sistema de destino y priorice el formato estándar definido por POSIX.

Problemas comunes

Se genera salida aunque el archivo no exista.

Es un comportamiento normal. basename extrae la última parte de la cadena de entrada sin verificar la existencia del archivo. Si el trabajo requiere un archivo real, se debe realizar una verificación separada de existencia y permisos.

Las rutas con espacios se dividen en varios argumentos.

Si no se encierra la variable entre comillas, puede ocurrir la separación de palabras y la expansión de glob del shell.

basename -- "$path"

Los sufijos no se eliminan

El sufijo debe coincidir exactamente con el final del nombre final. Se distingue entre mayúsculas y minúsculas y no se interpreta con expresiones regulares ni comodines.

FAQ

¿basename cambia el nombre real del archivo?

No. Solo calcula el nombre final desde la cadena de ruta ingresada y lo muestra, sin cambiar archivos o directorios.

¿Se puede eliminar la extensión con basename?

Se puede especificar el sufijo a eliminar como segundo argumento, como basename RUTA .txt. Para manejar varios nombres en un entorno GNU, se puede usar basename -s .txt NOMBRE....

¿basename funciona incluso con rutas que no existen?

Sí. Solo procesa la cadena de ruta, por lo que incluso sin el archivo real, muestra el último componente.

¿Cuál es la diferencia con dirname?

basename imprime el último nombre, y dirname imprime la parte del directorio excluyendo el último nombre.

Para comparar otras herramientas, consulte la Lista de comandos de uso frecuente en Linux. Para consultar las reglas y opciones, use Documentación oficial de GNU Coreutils basename y Especificación POSIX de basename.