Pobierz katalog nadrzędny dla pliku

24

Chcę uzyskać tylko nazwę katalogu nadrzędnego dla pliku.

Przykład: gdy mam path=/a/b/c/d/file, chcę tylko, da nie /a/b/c/d(z czego otrzymuję dirname $path) jako wynik.

Czy jest jakiś wyrafinowany sposób to zrobić?

shraddha
źródło

Odpowiedzi:

26

Brzmi to jak chcesz basename z tej dirname:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
Gordon Davisson
źródło
dlaczego otrzymuję zamiast katalogu nadrzędnego na Debianie?
Amir,
@Amir: Zaczynasz od pełnej ścieżki, czy po prostu nazwy pliku? Jeśli jest to tylko nazwa pliku, dirnamepolecenie przyjmie, że znajduje się w bieżącym katalogu (aka „.”).
Gordon Davisson
Cóż, używam tego:parentname="$(basename "$(dirname "$pwd")")"
Amir
1
@Amir: W zmiennych powłoki rozróżniana jest wielkość liter i PWDmuszą być wielkie litery. Spróbować parentname="$(basename "$(dirname "$PWD")")".
Gordon Davisson,
5

Możesz użyć pwd, aby uzyskać bieżący katalog roboczy, i użyć rozszerzenia parametrów, aby uniknąć rozrzucenia go do innej (pod) powłoki.

echo ${PWD##*/}

Edycja: sprawdzone źródło

ogień
źródło
Pytanie nie ma nic wspólnego z bieżącym katalogiem. Możesz użyć${path##*/}
Matteo,
2

Myślę, że to rozwiązanie z mniejszymi zasobami:

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

edycja: Przepraszamy, zagnieżdżone rozszerzenie nie jest możliwe w bash, ale działa w zsh. Wersja Bash:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
uzsolt
źródło
Niektóre przypadki krawędzi nie radzą sobie dobrze, głównie gdy nie ma pełnej ścieżki wielopoziomowej. Na przykład wypróbuj go z parametrem filepath=filelub ścieżka_pliku = / plik`.
Gordon Davisson,
W rzeczy samej. Ale czym jest katalog macierzysty foofile? Jeśli nie jest pełna, nie można ustalić ścieżki (być może foofileistniejący plik to nie tylko „ciąg”).
uzsolt
1

W skrócie, w jednej linii:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
julian67
źródło
2
czy możesz opracować odpowiednie procedury? może być pomocny dla przyszłych czytelników. proszę również nie pisać 1/2 linii odpowiedzi.
Lorenzo Von Matterhorn
0

Najbardziej podoba mi się odpowiedź Julian67, ale tutaj jest nieco rozszerzona wersja:

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
źródło