Une version encore plus générale qui permet d’utiliser des find
options:
#!/bin/bash
set -e
path="$1"
shift 1
while [[ $path != / ]];
do
find "$path" -maxdepth 1 -mindepth 1 "$@"
# Note: if you want to ignore symlinks, use "$(realpath -s "$path"/..)"
path="$(readlink -f "$path"/..)"
done
Par exemple (en supposant que le script soit enregistré sous find_up.sh
)
find_up.sh some_dir -iname "foo*bar" -execdir pwd \;
... affichera les noms de tous some_dir
les ancêtres de (avec lui-même) jusqu'à /
ce qu'un fichier contenant le motif se trouve.
Lors de l'utilisation readlink -f
du script ci-dessus, les liens symboliques suivront à la hausse, comme indiqué dans les commentaires. Vous pouvez utiliser à la realpath -s
place, si vous voulez suivre les chemins par nom ("/ foo / bar" ira jusqu'à "foo" même si "bar" est un lien symbolique) - cependant cela nécessite une installation realpath
qui n'est pas installée par défaut sur la plupart des plates-formes.
realpath -s
pour obtenir le comportement que vous souhaitez.readlink
ne fait pas partie de la norme. Un script portable pourrait être mis en œuvre avec uniquement les fonctionnalités du shell POSIX.find
oureadlink
. Je suggère de le changer pour quelque chose comme à la$curpath
place afin de ne pas masquer la variable shell.affichera le répertoire de niveau supérieur du référentiel actuel, si vous en êtes.
Autres options connexes:
la source
Une version généralisée de la réponse de Gilles, premier paramètre utilisé pour trouver la correspondance:
Maintient l'utilisation de sym-links.
la source
Trouver ne peut pas le faire. Je ne peux penser à rien de plus simple qu'une boucle de shell. (Non testé, suppose qu'il n'y en a pas
/.git
)Dans le cas spécifique d'un référentiel git, vous pouvez laisser git faire le travail à votre place.
la source
Si vous utilisez zsh avec la fonctionnalité étendue de globbing activée, vous pouvez le faire avec un oneliner:
Explication (citée de
man zshexpn
):Crédits:
Faux
sur#zsh
pour la suggestion initiale d'utilisation(../)#.git(:h)
.la source
(../)
fait-on… Oh, et qui / quoiFaux on #zsh
?(../)
seul ne veut pas dire grand-chose, mais(../)#
signifie qu'il faut essayer de développer le motif à l'intérieur de la parenthèse au moins 0 fois et d'utiliser uniquement ceux qui existent réellement sur le système de fichiers. Etant donné que nous étendons de 0 à n répertoires parents, nous recherchons la racine du système de fichiers (remarque: vous voudrez probablement ajouter quelque chose après le motif pour le rendre significatif, mais pour l’illumination, exécutezprint -l (../)#
). Et#zsh
est un canal IRC,Faux
est un nom d'utilisateur sur celui-ci.Faux
suggéré la solution, donc le crédit.(../)#.git(/Y1:a:h)
vous arrêter au premier trouvé (avec une version récente de zsh)setopt extended_glob
Cette version de findup prend en charge la syntaxe "find", comme la réponse de @ sinelaw, mais prend également en charge les liens symboliques sans avoir besoin de realpath. Il supporte également une fonction optionnelle "stop at", donc ça marche:
findup .:~ -name foo
... cherche foo sans passer par le répertoire home.la source
J'ai constaté que travailler avec des liens symboliques éliminait certaines des autres options. Surtout les réponses spécifiques Git. J'ai créé à mi-chemin mon propre favori à partir de cette réponse originale et plutôt efficace.
J'utilise des liens symboliques pour mes projets go, car go veut du code source à un emplacement donné et j'aime garder mes projets sous ~ / projects. Je crée le projet dans $ GOPATH / src et les lie symboliquement à ~ / projects. Ainsi, exécuter
git rev-parse --show-toplevel
imprime le répertoire $ GOPATH, pas le répertoire ~ / projects. Cette solution résout ce problème.Je réalise que la situation est très spécifique, mais je pense que la solution est précieuse.
la source
La solution de Vincent Scheib ne fonctionne pas pour les fichiers qui se trouvent dans le répertoire racine.
La version suivante le fait, et vous permet également de passer le répertoire de départ comme premier argument.
la source
J'ai modifié la solution de Sinelaw pour qu'elle soit POSIX. Il ne suit pas les liens symboliques et inclut la recherche dans le répertoire racine en utilisant une boucle do while.
la source