Obter o diretório pai para um arquivo

24

Quero obter apenas o nome do diretório pai de um arquivo.

Exemplo: quando tenho path=/a/b/c/d/file, quero apenas de não /a/b/c/d(do qual recebo dirname $path) como saída.

Existe alguma maneira sofisticada de fazer isso?

shraddha
fonte

Respostas:

26

Parece que você deseja o nome de base do dirname:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
Gordon Davisson
fonte
Por que estou recebendo. em vez do diretório pai no debian?
Amir
@Amir: Você está começando com um caminho completo ou apenas com um nome de arquivo? Se for apenas um nome de arquivo, o dirnamecomando assumirá que está no diretório atual (também conhecido como ".").
Gordon Davisson
bem, eu estou usando isso:parentname="$(basename "$(dirname "$pwd")")"
Amir
11
@Amir: As variáveis ​​do shell diferenciam maiúsculas de minúsculas e PWDdevem ser capitalizadas. Tente parentname="$(basename "$(dirname "$PWD")")".
Gordon Davisson
5

Você pode usar o pwd para obter o diretório de trabalho atual e usar a expansão de parâmetros para evitar bifurcá-lo em outro (sub) shell.

echo ${PWD##*/}

Edit: fonte comprovada

fogo
fonte
A questão não tem nada a ver com o diretório atual. Você poderia usar${path##*/}
Matteo
2

Eu acho que essa é uma solução com menos recursos:

 $ filepath=/a/b/c/d/file
 $ echo ${${filepath%/*}##*/}
 d

edit: Desculpe, a expansão aninhada não é possível no bash, mas funciona no zsh. Versão Bash:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
uzsolt
fonte
Existem alguns casos extremos que não funcionam bem, principalmente quando não há um caminho completo em vários níveis. Por exemplo, tente com filepath=fileou filepath = / file`.
Gordon Davisson
De fato. Mas qual é o diretório pai foofile? Se não for o caminho completo, não será possível saber (talvez se foofileum arquivo existente não seja apenas uma "string").
uzsolt
1

No bash, em uma linha:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
julian67
fonte
2
você pode elaborar os procedimentos envolvidos? pode ser útil para futuros leitores. Além disso, tente não escrever respostas para 1/2 linha.
Lorenzo Von Matterhorn
0

Eu gosto da resposta de Julian67 acima, mas aqui está uma versão expandida:

file_path = "a/b/c/d/file.txt"
parent=$(echo $file_path | sed -e 's;\/[^/]*$;;') # cut away "/file.txt";'$' is end of string
parent=$(echo $parent | sed -e 's;.*\/;;')  # cut away "/a/b/c/"
echo $parent # --> you get "d"
Dominic van der Zypen
fonte