2011-12-08 16 views
112

Se ho un percorso di file come ad esempio ...Ottenere il genitore di una directory in Bash

/home/smith/Desktop/Test 
/home/smith/Desktop/Test/ 

Come posso cambiare la stringa in modo che sia la directory genitore?

ad es.

+1

Si può semplicemente usare ''..'', ma forse non è proprio quello che avevi in ​​mente. –

risposta

161
dir=/home/smith/Desktop/Test 
parentdir="$(dirname "$dir")" 

Funziona anche se c'è una barra finale.

+9

le virgolette interne sono importanti o perderai tutti i tuoi dati – asdfasdfads

+4

e la variante che sto usando per ottenere il genitore della directory di lavoro corrente: 'parentdir = $ (dirname \' pwd \ ')' – TheGrimmScientist

+0

Il genitore della directory di lavoro corrente è semplicemente '..'. –

7

Se /home/smith/Desktop/Test/../ è ciò che si vuole:

dirname 'path/to/child/dir' 

come visto here.

+1

scusate, voglio dire come in uno script bash, ho una variabile con il percorso file – YTKColumba

+0

L'esecuzione di quel codice mi dà l'errore 'bash: dirname 'Test': sintassi errore: operatore aritmetico non valido (errore token è" 'Test' ") '. Anche il codice collegato è sbagliato. –

+0

prova solo ad eseguire 'dirname Test' dalla directory' Test' è in. – Jon

11

... ma ciò che è "visto here" è rotto. Ecco la correzione:

> pwd 
/home/me 
> x='Om Namah Shivaya' 
> mkdir "$x" && cd "$x" 
/home/me/Om Namah Shivaya 
> parentdir="$(dirname "$(pwd)")" 
> echo $parentdir 
/home/me 
1

A seconda se avete bisogno di percorsi assoluti si consiglia di fare un passo in più:

child='/home/smith/Desktop/Test/' 
parent=$(dirname "$child") 
abs_parent=$(realpath "$parent") 
-1

uso questo: export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")" se si desidera directory principale 4a

export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")" se si desidera la terza directory principale

export MYVAR="$(dirname "$(dirname $PWD)")" se si desidera la seconda directory principale

2

Basta usare echo $(cd ../ && pwd) mentre si lavora nella directory di cui si desidera scoprire la directory principale. Questa catena ha anche il vantaggio di non avere le barre finali.

+0

Non hai bisogno di 'echo' qui. –

5

Chiaramente la directory padre è dato semplicemente aggiungendo il dot-dot filename:

/home/smith/Desktop/Test/..  # unresolved path 

Ma si deve voler il risolto percorso (un percorso assoluto, senza alcun componente del percorso del puntino-dot):

/home/smith/Desktop    # resolved path 

Il problema con le risposte migliori che utilizzano dirname, è che essi non funzionano quando si entra in un percorso con dot-dots:

$ dir=~/Library/../Desktop/../.. 
$ parentdir="$(dirname "$dir")" 
$ echo $parentdir 
/Users/username/Library/../Desktop/.. # not fully resolved 

Questo è più potente:

dir=/home/smith/Desktop/Test 
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"` 

È possibile alimentarlo /home/smith/Desktop/Test/.., ma anche i percorsi più complessi come:

$ dir=~/Library/../Desktop/../.. 
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"` 
$ echo $parentdir 
/Users         # the fully resolved path! 
0

brutto ma efficace

function Parentdir() 

{

local lookFor_ parent_ switch_ i_ 

lookFor_="$1" 

#if it is not a file, we need the grand parent 
[ -f "$lookFor_" ] || switch_="/.." 

#length of search string 
i_="${#lookFor_}" 

#remove string one by one until it make sens for the system 
while [ "$i_" -ge 0 ] && [ ! -d "${lookFor_:0:$i_}" ]; 
do 
    let i_-- 
done 

#get real path 
parent_="$(realpath "${lookFor_:0:$i_}$switch_")" 

#done 
echo " 
lookFor_: $1 
{lookFor_:0:$i_}: ${lookFor_:0:$i_} 
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_}) 
parent_: $parent_ 
" 

}

lookFor_: /home/Om Namah Shivaya 
{lookFor_:0:6}: /home/ 
realpath {lookFor_:0:6}: /home 
parent_: /home 


lookFor_: /var/log 
{lookFor_:0:8}: /var/log 
realpath {lookFor_:0:8}: /UNIONFS/var/log 
parent_: /UNIONFS/var 


lookFor_: /var/log/ 
{lookFor_:0:9}: /var/log/ 
realpath {lookFor_:0:9}: /UNIONFS/var/log 
parent_: /UNIONFS/var 


lookFor_: /tmp//res.log/.. 
{lookFor_:0:6}: /tmp// 
realpath {lookFor_:0:6}: /tmp 
parent_:/


lookFor_: /media/sdc8/../sdc8/Debian_Master//a 
{lookFor_:0:35}: /media/sdc8/../sdc8/Debian_Master// 
realpath {lookFor_:0:35}: /media/sdc8/Debian_Master 
parent_: /media/sdc8 


lookFor_: /media/sdc8//Debian_Master/../Debian_Master/a 
{lookFor_:0:44}: /media/sdc8//Debian_Master/../Debian_Master/ 
realpath {lookFor_:0:44}: /media/sdc8/Debian_Master 
parent_: /media/sdc8 


lookFor_: /media/sdc8/Debian_Master/../Debian_Master/For_Debian 
{lookFor_:0:53}: /media/sdc8/Debian_Master/../Debian_Master/For_Debian 
realpath {lookFor_:0:53}: /media/sdc8/Debian_Master/For_Debian 
parent_: /media/sdc8/Debian_Master 


lookFor_: /tmp/../res.log 
{lookFor_:0:8}: /tmp/../ 
realpath {lookFor_:0:8}:/
parent_:/
Problemi correlati