Je veux trouver un fichier puis entrer dans le répertoire qui le contient. J'ai essayé find /media/storage -name "Fedora" | xargs cd
mais bien sûr, j'ai l' is not a directory
erreur.
Comment puis-je entrer son répertoire parent avec une commande d'une ligne?
shell
find
xargs
cd-command
Hrvoje T
la source
la source
shopt -s globstar
, vous pourriezcd /media/storage/**/Fedora
, mais cela n'arrête pas d'évaluer le glob lors de la première correspondance (donc c'est plus lent que la solution de steeldriver. Pour une utilisation interactive, ce que je ferais normalement est d'atteindre la souris et de copier / coller le nom du répertoire, (et alt + backspace si nécessaire pour supprimer les composants du chemin de fuite que je ne voulais pas), mais si vous faites beaucoup de choses, je suppose qu'une fonction shell pourrait valoir la peine d'être créée.xargs cd
ne peut pas fonctionner.cd
ne peut fonctionner que comme un shell intégré, car il doit modifier le contexte du shell lui-même. Il n'y a aucun moyen qu'unxargs
processus enfant puisse faire cela. IDK si c'est ce que vous vouliez dire "bien sûr", ou si le chemin quifind
imprime contient des espaces, qui sont divisés par xargs puisque vous ne l'avez pas utilisé-d \n
ou quoi que ce soit. Oufind -exec {} \;
.cd
comme ça.cd
est un bash intégré, s'ilcd
s'agissait d'une commande distincte, il changerait (son propre) répertoire, puis quitterait (vous ramenant au shell, qui est dans le même état que précédemment, aucun changement de répertoire).Réponses:
Au moins si vous avez GNU
find
, vous pouvez utiliser-printf '%h'
pour obtenir le répertoireVous pourriez donc probablement faire
Le
-quit
devrait empêcher plusieurs argumentscd
dans le cas où plus d'un fichier correspond.la source
-quit
n'est également pas nécessairement pris en charge. Dans NetBSD, cela s'appelle-exit
, voir unix.stackexchange.com/a/62883/117599Semblable à la solution de Steeldriver mais en utilisant
-execdir
(si votrefind
support, comme GNU ou FreeBSDfind
) en combinaison avecpwd
:-quit
est facultatif dans le cas où il n'y a qu'un seul résultat et en explorant l'ensemble du répertoire, il n'y a pas de problème. Sur NetBSD c'est-exit
et sur OpenBSD ça n'existe pas.la source
\;
?-exec
il indiquefind
la fin des paramètres de la commande à exécuter. Mais puisque nous voulons appelerpwd
sans paramètres ici, nous mettons le\;
droit après.find
implémentations qui prennent en charge execdir mais pas-printf %h
? Cela me semble peu probable. Malheureusement, ni l'un ni l'autre n'est requis par POSIX: /find
: freebsd.org/cgi/man.cgi?find%281%29 (Je viens de le confirmer sur une installation de FreeBSD 11).-quit
/ pas-exit
du tout.Vous pouvez faire exécuter find un nouveau shell dans le répertoire qu'il trouve.
, après quoi le répertoire courant sera celui qui contient un fichier nommé Fedora. ;)
Évidemment, cela ne fait que ressembler à ce que vous voulez si vous tapez des commandes de manière interactive.
la source
Avec
zsh
:à
cd
dans le premier répertoire (par ordre alphabétique) qui contient un fichier appeléFedora
.**
: n'importe quel niveau de répertoires (les répertoires cachés sont omis par défaut, utilisez leD
qualificatif glob pour les inclure)[1]
: seulement le premier:h
: modificateur de tête : prenez le dirname.Contrairement à
cd "$(find ...)"
, cela fonctionne également si le nom du répertoire se termine par un caractère de nouvelle ligne. Un autre avantage est que vous obtiendrez un message d'erreur sans correspondance lorsqu'il n'y a pas de répertoire correspondant (alors que dans la plupart des shells,cd ""
cela ne ferait rien en silence).Un inconvénient est qu'il ramperait tout
/media/storage
avant de revenir.la source
cd
avec plusieurs arguments ne regarde de toute façon que le premier argument, donccd $(dirname /media/storage/**/Fedora)
fonctionnerait (avecshopt -s globstar
) s'il n'y a pas d'espaces dans le chemin. Pour l' obtenir cité correctement, je pense qu'un tableau bash est plus facile:target=(/media/storage/**/Fedora); cd "${target%/*}"
. Mais à ce stade, il aurait été plus rapide d'utiliser la souris pour copier / coller la sortie de recherche au lieu de proposer cela de manière interactive.dirname
implémentations n'acceptent pas plus d'un argument. Notez que ce ne sont pas des espaces , c'est n'importe quel caractère actuellement$IFS
(espace, tabulation et saut de ligne par défaut) et des caractères génériques. Notez que sibash
l »cd
acceptent plus d'un argument dépend de la façon dont il a été compilé (CD_COMPLAINS
enconfig-top.h
). On peut imaginer que les futures versions debash
éventuellement implémenteront également la fonction deux arg comme dans zsh."${target%*/}"
s'étend qu'au premier élément du tableau (avec le/Fedora
dépouillé). Je pense que cette version est entièrement robuste contre tous les caractères possibles dans le chemin d'accès.