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?

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

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


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

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,'

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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.