Obter o caminho do diretório de arquivos do caminho do arquivo

No Bash, se VAR="/home/me/mydir/file.c" , como obtenho "/home/me/mydir" ?

dirname e basename são as ferramentas que você está procurando para extrair componentes de caminho:

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

Eles não são comandos internos do Bash, mas são parte do padrão POSIX (veja nome do dirname , basename ) e, portanto, devem estar disponíveis na grande maioria dos sistemas que executarão o Bash.

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

Para evitar dependência com basename e dirname

Em uma nota relacionada, se você tiver apenas o nome do arquivo ou o caminho relativo, o dirname próprio por si só não ajudará. Para mim, a resposta acabou sendo readlink .

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

Você pode então combinar os dois para obter apenas o diretório.

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

Se você deseja que os arquivos de destino sejam link simbólico, primeiro você pode verificar e obter o arquivo original. A cláusula if abaixo pode ajudá-lo.

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

Eu estava brincando com isso e surgiu com uma alternativa.

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

A parte que eu gostei é que foi fácil estender o backup da tree:

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

Aqui está um script que usei para corte recursivo. Substitua $ 1 pelo diretório que você deseja, é claro.

 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