Получить родительский каталог для файла

24

Я хочу получить только имя родительского каталога для файла.

Пример: когда у меня есть path=/a/b/c/d/file, я хочу только, dа не /a/b/c/d(что я получаю dirname $path) в качестве вывода.

Есть какой-нибудь изощренный способ сделать это?

шраддха
источник

Ответы:

26

Это звучит , как вы хотите , чтобы базовое имя из на имени папки:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
Гордон Дэвиссон
источник
почему я получаю. вместо родительского каталога в Debian?
Амир
@ Амир: Вы начинаете с полного пути или просто с имени файла? Если это просто имя файла, dirnameкоманда будет считать, что оно находится в текущем каталоге (он же ".").
Гордон Дэвиссон
хорошо, я использую это:parentname="$(basename "$(dirname "$pwd")")"
Амир
1
@Amir: переменные оболочки чувствительны к регистру и PWDдолжны быть написаны заглавными буквами. Попробуй parentname="$(basename "$(dirname "$PWD")")".
Гордон Дэвиссон
5

Вы можете использовать pwd, чтобы получить текущий рабочий каталог, и использовать расширение параметров, чтобы избежать разветвления его в другую (под) оболочку.

echo ${PWD##*/}

Редактировать: проверенный источник

Пожар
источник
Вопрос не имеет ничего общего с текущим каталогом. Вы могли бы использовать${path##*/}
Маттео
2

Я думаю, что это решение с меньшими ресурсами:

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

edit: Извините, вложенное расширение невозможно в bash, но оно работает в zsh. Bash-версия:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
uzsolt
источник
Есть некоторые крайние случаи, с которыми это не справляется, главным образом, когда нет полного многоуровневого пути. Например, попробуйте с помощью filepath=fileили filepath = / file`.
Гордон Дэвиссон
В самом деле. Но что является родительским каталогом foofile? Если это не полный путь, не могу знать (возможно, если foofileсуществующий файл не только «строка»).
uzsolt
1

В bash, в одну строку:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
julian67
источник
2
Можете ли вы разработать процедуры? это может помочь будущим читателям. также, пожалуйста, постарайтесь не писать ответы в 1/2 строки.
Лоренцо фон Маттерхорн
0

Мне больше нравится ответ Julian67 выше, но вот немного расширенная версия:

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"
Доминик ван дер Зипен
источник