Récupère le répertoire parent d'un fichier

24

Je souhaite obtenir uniquement le nom du répertoire parent d'un fichier.

Exemple: Quand je l'ai path=/a/b/c/d/file, je veux seulement det non /a/b/c/d(dont je tire dirname $path) comme sortie.

Existe-t-il un moyen sophistiqué de procéder?

shraddha
la source

Réponses:

26

Il semble que vous souhaitiez le nom de base du nom de répertoire:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
Gordon Davisson
la source
pourquoi je reçois. au lieu du répertoire parent sur debian?
Amir
@Amir: Commencez-vous par un chemin complet, ou juste un nom de fichier? Si c'est juste un nom de fichier, la dirnamecommande supposera qu'il se trouve dans le répertoire courant (aka ".").
Gordon Davisson
eh bien, j'utilise ceci:parentname="$(basename "$(dirname "$pwd")")"
Amir
1
@Amir: les variables shell sont sensibles à la casse et PWDdoivent être capitalisées. Essayez parentname="$(basename "$(dirname "$PWD")")".
Gordon Davisson
5

Vous pouvez utiliser pwd pour obtenir le répertoire de travail actuel et utiliser l' expansion des paramètres pour éviter de le bifurquer dans un autre (sous) shell.

echo ${PWD##*/}

Edit: source éprouvée

Feu
la source
La question n'a rien à voir avec le répertoire courant. Vous pouvez utiliser${path##*/}
Matteo
2

Je pense que c'est une solution moins gourmande en ressources:

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

edit: Désolé, l'expansion imbriquée n'est pas possible dans bash, mais cela fonctionne dans zsh. Version basique:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
Uzsolt
la source
Il y a des cas marginaux que cela ne gère pas bien, principalement lorsqu'il n'y a pas de chemin multiniveaux complet. Par exemple, essayez-le avec filepath=fileou filepath = / file`.
Gordon Davisson
En effet. Mais quel est le répertoire parent de foofile? S'il n'est pas complet, le chemin ne peut pas le savoir (peut-être s'il foofiles'agit d'un fichier existant et pas seulement d'une "chaîne").
uzsolt
1

En bash, en une seule ligne:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
julian67
la source
2
pouvez-vous s'il vous plaît élaborer les procédures impliquées? il peut être utile aux futurs lecteurs. essayez également de ne pas écrire de réponses sur 1/2 ligne.
Lorenzo Von Matterhorn
0

J'aime la réponse de Julian67 ci-dessus, mais voici un peu une version étendue:

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
la source