Exclure un sous-répertoire à l'aide de find


115

J'ai une structure de répertoires comme celle-ci

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

Il y a un sous-dossier entrant dans tous les dossiers du répertoire Data. Je veux obtenir tous les fichiers de tous les dossiers et sous-dossiers sauf les répertoires def / entrant et 456 / entrant. J'ai essayé avec la commande suivante

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

mais cela ne fonctionne pas comme prévu.

Ravi


3
Ce n'est pas un bon conseil, mais cela vous permettra de vous sortir de beaucoup de situations rapidement et sale: grep -v somethingfaites-le pour exclure tout ce que vous ne voulez pas
Miquel

Réponses:


206

Cela marche:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Explication:

  • find /home/feeds/data: démarrer la recherche récursivement à partir du chemin spécifié
  • -type f: rechercher uniquement des fichiers
  • -not -path "*def/incoming*": n'incluez rien avec def/incomingdans son chemin
  • -not -path "*456/incoming*": n'incluez rien avec 456/incomingdans son chemin

obtenir une erreur "trouver: mauvaise option -pas de trouver: liste de prédicat-liste de chemin"
Ravi

@Ravi utilisez-vous bash shell? Je viens de tester cela sur mon terminal et cela fonctionne pour moi. Essayez plutôt de copier et coller la solution si vous avez apporté des modifications à votre script.
sampson-chen

Cela fonctionne, mais il répertorie les répertoires et non les fichiers dans ces répertoires.
Ravi

1
-pathcorrespond à toute la chaîne, donc si vous le faites find ., vos -pathchaînes doivent être./path/to/directory/*
Heath Borders

1
FYI fonctionnera -not -pathcertainement dans cet exemple, mais findcontinue d'itérer dans la structure de répertoires et d'utiliser des cycles de processeur pour parcourir tous ces répertoires / fichiers. pour éviter findd'itérer sur ces répertoires / fichiers (peut-être qu'il y a des millions de fichiers), vous devez utiliser -prune(l' -pruneoption est cependant difficile à utiliser).
Trevor Boyd Smith

9

Juste pour la documentation: vous devrez peut-être creuser plus profondément car il y a beaucoup de constellations de recherche et de saut (comme je devais le faire). Il se peut que ce prunesoit votre ami pendant que-not -path ne fasse pas ce que vous attendez.

Voici donc un exemple précieux de 15 exemples de recherche qui excluent les répertoires:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

Pour créer un lien vers la question initiale, l'exclusion a finalement fonctionné pour moi comme ceci:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Ensuite, si vous souhaitez trouver un fichier et toujours exclure les chemins, ajoutez simplement | grep myFile.txt.

Cela peut également dépendre de votre version de recherche. Je vois:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5

-namecorrespond uniquement au nom du fichier, pas au chemin complet. Vous voulez utiliser à la -pathplace, pour les parties dans lesquelles vous élaguez les répertoires comme def/incoming.


2
find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

7
Certaines explications pourraient en faire une bien meilleure réponse.
Cris Luengo

Merci pour cet extrait de code, qui pourrait fournir une aide limitée à court terme. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites
Shawn C.

1
Remarque: cette astuce ne fonctionne pas si on l'utilise find ... -print0en conjonction avec une version ultérieurexargs -0
phs

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.