Obtener el directorio principal para un archivo

24

Quiero obtener solo el nombre del directorio principal para un archivo.

Ejemplo: cuando tengo path=/a/b/c/d/file, solo quiero dy no /a/b/c/d(que obtengo dirname $path) como salida.

¿Hay alguna forma sofisticada de hacer esto?

shraddha
fuente

Respuestas:

26

Parece que quieres el nombre base del nombre del directorio:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
Gordon Davisson
fuente
¿Por qué estoy recibiendo? en lugar del directorio padre en debian?
Amir
@Amir: ¿Estás comenzando con una ruta completa o solo un nombre de archivo? Si es solo un nombre de archivo, el dirnamecomando asumirá que está en el directorio actual (también conocido como ".").
Gordon Davisson
bueno, estoy usando esto:parentname="$(basename "$(dirname "$pwd")")"
Amir
1
@Amir: las variables de Shell distinguen entre mayúsculas y minúsculas y PWDdeben escribirse en mayúscula Tratar parentname="$(basename "$(dirname "$PWD")")".
Gordon Davisson
5

Puede usar pwd para obtener el directorio de trabajo actual y usar la expansión de parámetros para evitar bifurcarlo en otro (sub) shell.

echo ${PWD##*/}

Editar: fuente probada

fuego
fuente
La pregunta no tiene nada que ver con el directorio actual. Podrías usar${path##*/}
Matteo
2

Creo que esta es una solución con menos recursos:

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

editar: Lo sentimos, la expansión anidada no es posible en bash, pero funciona en zsh. Versión Bash:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
uzsolt
fuente
Hay algunos casos extremos que esto no se maneja bien, principalmente cuando no hay una ruta multinivel completa. Por ejemplo, pruébelo con filepath=fileo filepath = / file`.
Gordon Davisson el
En efecto. ¿Pero de qué es el directorio padre foofile? Si no está completa, la ruta no se puede saber (tal vez si foofilees un archivo existente, no solo una "cadena").
uzsolt
1

En bash, en una línea:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
julian67
fuente
2
¿puede por favor elaborar los procedimientos involucrados? Puede ser de ayuda para futuros lectores. Además, trate de no escribir respuestas de 1/2 línea.
Lorenzo Von Matterhorn
0

Me gusta más la respuesta de Julian67, pero aquí hay una versión un poco ampliada:

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
fuente