Obtener la ruta del directorio de archivos desde la ruta del archivo

En Bash, si VAR="/home/me/mydir/file.c" , ¿cómo obtengo "/home/me/mydir" ?

dirname y basename son las herramientas que está buscando para extraer componentes de ruta:

 $ VAR=/home/me/mydir/file.c $ DIR=$(dirname "${VAR}") $ echo "${DIR}" /home/me/mydir $ basename "${VAR}" file.c 

No son comandos internos de Bash, pero forman parte del estándar POSIX (consulte dirname , basename ) y, por lo tanto, deberían estar disponibles en la gran mayoría de los sistemas que ejecutarán Bash.

 $ export VAR=/home/me/mydir/file.c $ export DIR=${VAR%/*} $ echo "${DIR}" /home/me/mydir $ echo "${VAR##*/}" file.c 

Para evitar la dependencia con basename y dirname

En una nota relacionada, si solo tiene el nombre de archivo o la ruta relativa, dirname por sí solo no ayudará. Para mí, la respuesta terminó siendo readlink .

 fname='txtfile' echo $(dirname "$fname") # output: . echo $(readlink -f "$fname") # output: /home/me/work/txtfile 

A continuación, puede combinar los dos para obtener solo el directorio.

 echo $(dirname $(readlink -f "$fname")) # output: /home/me/work 

Si le importa que los archivos de destino sean un enlace simbólico, primero puede verificarlo y obtener el archivo original. La siguiente cláusula puede ayudarte.

 if [ -h $file ] then base=$(dirname $(readlink $file)) else base=$(dirname $file) fi 

Estaba jugando con esto y se me ocurrió una alternativa.

 $ VAR=/home/me/mydir/file.c $ DIR=`echo $VAR |xargs dirname` $ echo $DIR /home/me/mydir 

La parte que me gustó es que fue fácil extender la copia de seguridad del árbol:

 $ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname` $ echo $DIR /home 

Aquí hay un script que utilicé para recortar recursivamente. Reemplace $ 1 con el directorio que desee, por supuesto.

 BASEDIR="$1" IFS=$'\n' cd $BASEDIR for f in $(find . -type f -name ' *') do DIR=$(dirname "$f") DIR=${DIR:1} cd $BASEDIR$DIR rename 's/^ *//' * done