Artículos etiquetados "Unix"

Descomponer una ruta en directorios, nombre de archivo y extensión en Bash

Una tarea que puede ser bastante común a la hora de escribir scripts o aplicaciones que trabajen con el sistema de archivos es la necesidad de descomponer una ruta completa del tipo «/directorio/subdirectorio/…/…/archivo.extension» para obtener por separado el nombre de archivo, la extensión y la ruta de directorios. De hecho, fue una de las necesidades que me ha surgido estos días, escribiendo un Shell Script un tanto grande en el que necesitaba obtener el nombre de un archivo de una ruta completa así como la estructura de directorios hasta el mismo.

Dado que me suele gustar, al escribir scripts de cierto tamaño, dividirlos por bloques de código independientes, voy a publicar este como una solución aislada para solventar el problema de descomponer rutas aunque cuando lo volváis a ver en el script que aún no he terminado aparecerá como una función por la comodidad que representan y porque facilitan mucho la lectura del código en scripts de muchas lineas. Sin más preámbulos, vamos manos a la obra:

Dado que este código ahora es independiente, he realizado algunos cambios como que tome la entrada de datos a modo de parametros tras el nombre del script por lo que la ruta a descomponer, deberá ir tras el nombre del script en lo que seria el parámetro $1, es decir, tendriamos que pasárselo de la siguiente manera:

./script.sh /ruta/que/queramos/descomponer/archivo.extension
Por el mismo motivo, lo he dispuesto de forma que la salida del mismo sea la salida estándar mostrando el valor de cada una de las variables que intervienen en el proceso.

También he comentado las lineas relevantes ya que creo que será mejor explicar cada una de las lineas en el mismo punto donde aparece. Así pues, este es el script:

 



#!/bin/bash
# Script para descomponer una ruta completa a un archivo o directorio, obteniendo
# el nombre de archivo y extensión (si existen) y ruta hasta los mismos
for RutaCompleta in $1
do
# Comenzamos extrayendo la parte derecha desde el ultimo caracter "/", es decir, el archivo
NombreArchivo="${RutaCompleta##*/}"
# Longitud de la ruta es el total de caracteres menos el largo del nombre de archivo
LargoRuta="${#RutaCompleta} - ${#NombreArchivo}"
# Extraermos la ruta desde el caracter 0 hasta el caracter final de largo de ruta
RutaSola="${RutaCompleta:0:$LargoRuta}"
# Lo siguiente es extraer nombre de archivo
NombreSolo="${NombreArchivo%.[^.]*}"
# Extension se obtiene eliminando del nombre completo el nombre mas el punto
Extension="${NombreArchivo:${#NombreSolo} + 1}"
# Las 2 lineas anteriores fallan si no hay extension por lo que es necesario comprobar que no
# se de el caso de que haya extension pero no nombre ya que en ese caso la ext seria el nombre
if [[ -z "$NombreSolo" && -n "$Extension" ]]; then
NombreSolo=".$Extension"
Extension=""
fi
done
# Este es el resultado del script
echo
echo "Este es el resultado del script:"
echo
echo La ruta completa es:
echo $RutaCompleta
echo
echo "Ruta.........: \"$RutaSola\""
echo "Nombre.......: \"$NombreSolo\""
echo "Extension....: \"$Extension\""
echo


Si lo ejecutamos, la salida del mismo, según está, sería similar a esto
:

 


$ ./descomp.sh /dir1/subdir1/subdir2/archivo.txt

Este es el resultado del script:

La ruta completa es:
/dir1/subdir1/subdir2/archivo.txt

Ruta………: «/dir1/subdir1/subdir2/»
Nombre…….: «archivo»
Extension….: «txt»


Ahora bien, hay que tener en cuenta que si lo vamos a utilizar como una función llamada desde otro script o simplemente como un bloque de código incrustado entre las lineas, habría que hacerle algunos cambios, pero dado que lo estoy utilizando en otro script que voy a publicar aquí también, no lo explicaré aún ya que es cuestión de tiempo que me toque hacerlo.


 

 

leer más