Comment exclure ce dossier / current / dot de la recherche «type d»

186
find . -type d

peut être utilisé pour trouver tous les répertoires sous un certain point de départ. Mais il renvoie également le répertoire courant ( .), ce qui peut être indésirable. Comment peut-il être exclu?

Matthias Ronge
la source

Réponses:

194

Solution POSIX 7 :

find . ! -path . -type d

Pour ce cas particulier ( .), les golfs sont meilleurs que la mindepthsolution (24 contre 26 caractères), bien que ce soit probablement un peu plus difficile à taper à cause du! .

Pour exclure d'autres répertoires, cela jouera moins bien et nécessite une variable pour DRYness:

D="long_name"
find "$D" ! -path "$D" -type d

Mon arbre de décision entre !et -mindepth:

  • scénario? Utilisez !pour la portabilité.
  • session interactive sur GNU?
    • exclure .? Jetez une pièce.
    • exclure long_name? Utilisez -mindepth.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
si vous avez besoin d'exclure plusieurs chemins, find /path/ ! -path "/path/first" ! -path "/path/second"est-ce que c'est le seul moyen?
Vincent De Smet
2
@VincentDeSmet voulez-vous exclure uniquement ces chemins, ou ne pas y revenir? Si juste les chemins, vous pouvez utiliser find / ! -regex '/\(a\|b\)/.*'ou plus simplement, passer par grep. Pour ne pas récurer, ce qui précède serait très inefficace et vous devriez utiliser -prune: stackoverflow.com/questions/1489277/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
mon problème était le suivant: je voulais supprimer récursivement tout dans un répertoire à l'exception d'un sous-répertoire. J'utilisais findavec greppour exclure le répertoire mais le répertoire parent était toujours là, ce qui a quand même tout supprimé.
Vincent De Smet
@VincentDeSmet Je ne vois pas de solution directe avec find, vous auriez besoin de vérifier les préfixes: stackoverflow.com/questions/17959317/... Mais une boucle Bash for peut le gérer :-)
Ciro Santilli 郝海东 冠状 病 六四 事件法轮功
Vous voulez probablement échapper au caractère d'exclamation ( \!) pour être du bon côté. Tous les exemples de ma machine l' man findont échappé, il semble donc que ce soit probablement une bonne idée ™. Edit - Juste remarqué, il dit même explicitement:! expr True if expr is false. This character will also usually need protection from interpretation by the shell.
Adrian Günter
201

Non seulement la profondeur de récursivité de findpeut être contrôlée par le -maxdepthparamètre, mais la profondeur peut également être limitée à partir du «haut» en utilisant le -mindepthparamètre correspondant . Donc, ce dont on a réellement besoin, c'est:

find . -mindepth 1 -type d
Matthias Ronge
la source
5
fonctionne sur GNU find, mais est malheureusement une extension gnu de la find POSIX 7 , et même le LSB utilise les utilitaires shell POSIX (pas les utilitaires GNU étendus)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
6
Cela a fonctionné pour moi. À savoir:find . -mindepth 1 -maxdepth 1 -type d ...
racl101
19

J'utilise find ./* <...>quand cela ne me dérange pas d'ignorer les fichiers dotfiles de premier niveau (le *glob ne les correspond pas par défaut dans bash - voir l'option 'dotglob' dans le shopt intégré: https://www.gnu.org/software/bash /manual/html_node/The-Shopt-Builtin.html ).

eclipse tmp # find.
.
./écran
./screen/.testfile2
./.X11-unix
./.ICE-unix
./tmux-0
./tmux-0/default
eclipse tmp # find ./*
./écran
./screen/.testfile2
./tmux-0
./tmux-0/default
Milos Ivanovic
la source
FYI. n'utilisez pas cette astuce avec l' -execoption. Par exemple, si vous essayez find dir/* -type d -exec rmdir {} \;, vous verrez des erreurs.
plhn
Vous vous trompez, ou vous êtes peut-être déconseillé. Cette commande fonctionnera bien. Si vous voyez des erreurs, elles proviendront rmdiret vous diront probablement que les répertoires ne sont pas vides puisqu'ils findeffectueront une recherche approfondie dans les répertoires, montrant les parents avant leurs enfants.
Milos Ivanovic
2
Remarque: «ignorer les fichiers dotfiles de premier niveau» signifie également exclure tous les fichiers / répertoires cachés.
Jonathan H
2

Eh bien, une solution de contournement simple également (la solution ne fonctionnait pas pour moi sous windows git bash)

find * -type d

Ce n'est peut-être pas très performant, mais cela fait le travail, et c'est ce dont nous avons parfois besoin.

[Edit]: Comme @AlexanderMills l'a commenté, il ne montrera pas les répertoires cachés à l'emplacement racine (par exemple ./.hidden), mais il affichera les sous-répertoires cachés (par exemple ./folder/.hiddenSub). [Testé avec git bash sous Windows]

StackHola
la source