web-dev-qa-db-fra.com

Comment exclure un répertoire dans find. commander

J'essaie d'exécuter une commande find pour tous les fichiers JavaScript, mais comment puis-je exclure un répertoire spécifique?

Voici le code find que nous utilisons.

for file in $(find . -name '*.js')
do 
  Java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done
1180
helion3

Utilisez le commutateur -Prune. Par exemple, si vous souhaitez exclure le répertoire misc, ajoutez simplement un -path ./misc -Prune -o à votre commande de recherche:

find . -path ./misc -Prune -o -name '*.txt' -print

Voici un exemple avec plusieurs répertoires:

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -Prune -o -print

Ici, nous excluons dir1, dir2 et dir, car dans find expressions, il s'agit d'une action qui agit sur le critère -path dir1 -o -path dir2 -o -path dir3 (si dir1 ou dir2 ou dir), ANDé avec type -d.

Une autre action est -o print, il suffit d’imprimer.

922
f10bit

Si -Prune ne fonctionne pas pour vous, cela va:

find -name "*.js" -not -path "./directory/*"

Caveat: nécessite de parcourir tous les répertoires indésirables.

1783
GetFree

Je trouve plus facile de raisonner sur les solutions suivantes que d’autres solutions proposées:

find build -not \( -path build/external -Prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -Prune \) -not \( -path build/blog -Prune \) -name \*.js

Remarque importante: les chemins que vous tapez après -path doivent correspondre exactement à ceux que find imprimerait sans exclusion. Si cette phrase vous rend confus, assurez-vous simplement d'utiliser des chemins d'accès complets dans la commande entière comme ceci: find /full/path/ -not \( -path /full/path/exclude/this -Prune \) .... Voir la note [1] si vous souhaitez mieux comprendre.

À l'intérieur \( et \) est une expression qui correspond exactement build/external (voir la remarque importante ci-dessus), et en cas de succès, évitera de traverser quoi que ce soit en dessous . Ceci est ensuite groupé en une seule expression avec la parenthèse échappée et préfixé par -not, ce qui fera que find ignore tout ce qui a été mis en correspondance par cette expression.

On pourrait se demander si l'ajout de -not ne fera pas apparaître tous les autres fichiers masqués par -Prune, et la réponse est non. Le fonctionnement de -Prune consiste à ignorer définitivement tout fichier qui, une fois atteint, est situé au-dessous de ce répertoire.

Cela vient d'un cas d'utilisation réel, où j'avais besoin d'appeler yui-compressor sur certains fichiers générés par wintersmith, tout en laissant de côté les autres fichiers à envoyer tels quels.


Note [1]: Si vous voulez exclure /tmp/foo/bar et que vous exécutez find comme ceci "find /tmp \(...", vous devez spécifier -path /tmp/foo/bar. Si par contre vous exécutez find comme ceci cd /tmp; find . \(..., vous devez alors spécifier -path ./foo/bar.

422
Daniel C. Sobral

Il existe clairement une certaine confusion quant à la syntaxe à adopter pour ignorer un répertoire.

Opinion GN

To ignore a directory and the files under it, use -Prune

De la GNU page de recherche find )

Raisonnement

-Prune empêche find de descendre dans un répertoire. Il suffit de spécifier -not -path pour descendre dans le répertoire skipped , mais -not -path sera faux chaque fois que find testera chaque fichier.

Problèmes avec -Prune

-Prune fait ce à quoi il est destiné, mais il vous reste certaines choses à prendre en compte lors de son utilisation.

  1. find imprime le répertoire élagué.

    • TRUE C'est le comportement prévu, il ne descend pas dedans. Pour éviter d’imprimer le répertoire complètement, utilisez une syntaxe qui l’aborde logiquement.
  2. -Prune ne fonctionne qu'avec -print et pas d'autres actions.

    • PAS VRAI. -Prune fonctionne avec toutes les actions sauf -delete. Pourquoi ça ne marche pas avec delete? Pour que -delete fonctionne, find doit parcourir le répertoire dans l'ordre DFS, puisque -delete supprime d'abord les feuilles. , puis les parents des feuilles, etc ... Mais pour spécifier -Prune pour donner un sens, find a besoin de frapper un répertoire et d'arrêter de le descendre, ce qui n'a aucun sens avec -depth ou -delete sur.

Performance

J'ai mis en place un test simple des trois réponses les plus votées sur cette question (remplacé -print par -exec bash -c 'echo $0' {} \; pour afficher un autre exemple d'action). Les résultats sont ci-dessous

----------------------------------------------
# of files/dirs in level one directories
.performance_test/Prune_me     702702    
.performance_test/other        2         
----------------------------------------------

> find ".performance_test" -path ".performance_test/Prune_me" -Prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 23513814

> find ".performance_test" -not \( -path ".performance_test/Prune_me" -Prune \) -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 10670141

> find ".performance_test" -not -path ".performance_test/Prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 864843145

Conclusion

Les deux méthodes syntaxe de f10bit et syntaxe de Daniel C. Sobral ont mis 10 à 25 ms à exécuter en moyenne. La syntaxe de GetFree , qui n'utilise pas -Prune, a pris 865ms. Donc, oui, c'est un exemple assez extrême, mais si vous vous souciez de l'exécution et que vous faites quelque chose de très intensif à distance, vous devriez utiliser -Prune.

Note La syntaxe de Daniel C. Sobral a exécuté la meilleure des deux syntaxes -Prune; mais je soupçonne fortement que cela est le résultat d'une mise en cache qui a inversé l'ordre dans lequel les deux exécutions ont eu le résultat opposé, alors que la version non-Prune était toujours la plus lente.

Test Script

#!/bin/bash

dir='.performance_test'

setup() {
  mkdir "$dir" || exit 1
  mkdir -p "$dir/Prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
    "$dir/other"

  find "$dir/Prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
  find "$dir/Prune_me" -type d -exec touch '{}'/{1..1000} \;
  touch "$dir/other/foo"
}

cleanup() {
  rm -rf "$dir"
}

stats() {
  for file in "$dir"/*; do
    if [[ -d "$file" ]]; then
      count=$(find "$file" | wc -l)
      printf "%-30s %-10s\n" "$file" "$count"
    fi
  done
}

name1() {
  find "$dir" -path "$dir/Prune_me" -Prune -o -exec bash -c 'echo "$0"'  {} \;
}

name2() {
  find "$dir" -not \( -path "$dir/Prune_me" -Prune \) -exec bash -c 'echo "$0"' {} \;
}

name3() {
  find "$dir" -not -path "$dir/Prune_me*" -exec bash -c 'echo "$0"' {} \;
}

printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"

printf "\nRunning performance test...\n\n"

echo \> find \""$dir"\" -path \""$dir/Prune_me"\" -Prune -o -exec bash -c \'echo \"\$0\"\'  {} \\\;
name1
s=$(date +%s%N)
name1_num=$(name1 | wc -l)
e=$(date +%s%N)
name1_perf=$((e-s))
printf "  [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n"

echo \> find \""$dir"\" -not \\\( -path \""$dir/Prune_me"\" -Prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N)
name2_num=$(name2 | wc -l)
e=$(date +%s%N)
name2_perf=$((e-s))
printf "  [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"

echo \> find \""$dir"\" -not -path \""$dir/Prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\;
name3
s=$(date +%s%N)
name3_num=$(name3 | wc -l)
e=$(date +%s%N)
name3_perf=$((e-s))
printf "  [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"

echo "Cleaning up test files..."
cleanup
192
BroSlow

Une option serait d'exclure tous les résultats contenant le nom du répertoire avec grep. Par exemple:

find . -name '*.js' | grep -v excludeddir
60
Joshua

C'est le seul qui a fonctionné pour moi.

find / -name NameOfFile ! -path '*/Directory/*'

Recherche de "NameOfFile" à l'exclusion de "Répertoire". Mettre l'accent sur les étoiles *.

47
DimiDak

Je préfère la notation -not _ ... c'est plus lisible:

find . -name '*.js' -and -not -path directory
41
mpapis

Utilisez l'option -Prune. Donc, quelque chose comme:

find . -type d -name proc -Prune -o -name '*.js'

Le '-type d -name proc -Prune' recherche uniquement les répertoires nommés proc à exclure.
Le "-o" est un opérateur "OU".

19
Drew Frezell

C'est le format que j'ai utilisé pour exclure certains chemins:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

J'ai utilisé cela pour trouver tous les fichiers qui ne sont pas dans les chemins ". *"

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
15
user1882879

-Prune fonctionne définitivement et constitue la meilleure réponse car elle empêche de descendre dans le répertoire que vous souhaitez exclure. -not -path qui recherche toujours le répertoire exclu, il n'imprime tout simplement pas le résultat, ce qui peut poser problème si le répertoire exclu est monté sur un volume réseau ou si vous n'avez pas d'autorisations.

La difficulté réside dans le fait que find est très particulier sur l’ordre des arguments. Par conséquent, si vous ne les comprenez pas correctement, votre commande risque de ne pas fonctionner. L'ordre des arguments est généralement comme tel:

find {path} {options} {action}

{path}: Met en premier tous les arguments liés au chemin, comme . -path './dir1' -Prune -o

{options}: J'ai le plus de succès en plaçant -name, -iname, etc comme dernière option de ce groupe. Par exemple. -type f -iname '*.js'

{action}: Vous voudrez ajouter -print lorsque vous utilisez -Prune

Voici un exemple de travail:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -Prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -Prune -o -type f -iname '*.js' -print
14
wisbucky

L'approche -path -Prune fonctionne également avec des caractères génériques dans le chemin. Voici une instruction find qui trouvera les répertoires d'un serveur git servant plusieurs référentiels git, en laissant de côté les répertoires internes de git:

find . -type d \
   -not \( -path */objects -Prune \) \
   -not \( -path */branches -Prune \) \
   -not \( -path */refs -Prune \) \
   -not \( -path */logs -Prune \) \
   -not \( -path */.git -Prune \) \
   -not \( -path */info -Prune \) \
   -not \( -path */hooks -Prune \)  
10
Wolfgang Fahl

Il y a beaucoup de bonnes réponses, il m'a fallu un peu de temps pour comprendre à quoi servait chaque élément de la commande et la logique qui la sous-tend.

find . -path ./misc -Prune -o -name '*.txt' -print

find commencera à chercher des fichiers et des répertoires dans le répertoire actuel, d'où le find ..

L'option -o désigne un OR logique et sépare les deux parties de la commande:

[ -path ./misc -Prune ] OR [ -name '*.txt' -print ]

Tout répertoire ou fichier qui est pas le répertoire ./misc ne passera pas le premier test -path ./misc. Mais ils seront testés contre la deuxième expression. Si leur nom correspond au motif *.txt, ils sont imprimés en raison de l'option -print.

Lorsque find atteint le répertoire ./misc, ce répertoire ne satisfait que la première expression. Donc, l'option -Prune lui sera appliquée. Il indique à la commande de recherche de pas explorer ce répertoire. Ainsi, tout fichier ou répertoire dans ./misc ne sera même pas exploré par find, ne sera pas testé par rapport à la deuxième partie de l'expression et ne sera pas imprimé.

8
Istopopoki

Pour exclure plusieurs répertoires:

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)

Pour ajouter des répertoires, ajoutez -o -path "./dirname/*":

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)

Mais peut-être devriez-vous utiliser un expression régulière , s'il y a beaucoup de répertoires à exclure.

8
JBENOIT

Pour une solution de travail (testée sur Ubuntu 12.04 (Precise Pangolin)) ...

find ! -path "dir1" -iname "*.mp3"

recherche les fichiers MP3 dans le dossier actuel et les sous-dossiers sauf dans le sous-dossier dir1.

Utilisation:

find ! -path "dir1" ! -path "dir2" -iname "*.mp3"

... pour exclure dir1 ET dir2

7
james dupin

Vous pouvez utiliser l'option Prune pour y parvenir. Comme par exemple:

find ./ -path ./beta/* -Prune -o -iname example.com -print

Ou l'option inverse grep “grep -v”:

find -iname example.com | grep -v beta

Vous trouverez des instructions détaillées et des exemples dans la commande de recherche Linux exclut les répertoires de la recherche.

6
Siju V
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'

semble fonctionner comme

find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)

et il est plus facile de se souvenir de l'OMI.

4
Funkodebat

Pour ceux des anciennes versions d'UNIX qui ne peuvent pas utiliser - path ou - not

Testé sur SunOS 5.10 bash 3.2 et SunOS 5.11 bash 4.4

find . -type f -name "*" -o -type d -name "*excluded_directory*" -Prune -type f
3
JaredTS486

TLDR: comprendre vos répertoires racines et adapter votre recherche à partir de cet emplacement, à l’aide de l’option _-path <excluded_path> -Prune -o_. N'incluez pas un _/_ final à la fin du chemin exclu.

Exemple:

_find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print_


Pour utiliser efficacement la find, j'estime qu'il est impératif de bien comprendre la structure de répertoires de votre système de fichiers. Sur mon ordinateur personnel, j'ai des disques durs multi-To. Environ la moitié de ce contenu est sauvegardé à l'aide de rsnapshot (c'est-à-dire, rsync). Bien que la sauvegarde soit effectuée sur un lecteur physiquement indépendant (en double), il est monté dans le répertoire racine de mon système (_/_): _/mnt/Backups/rsnapshot_backups/_:

_/mnt/Backups/
└── rsnapshot_backups/
    ├── hourly.0/
    ├── hourly.1/
    ├── ...
    ├── daily.0/
    ├── daily.1/
    ├── ...
    ├── weekly.0/
    ├── weekly.1/
    ├── ...
    ├── monthly.0/
    ├── monthly.1/
    └── ...
_

Le répertoire _/mnt/Backups/rsnapshot_backups/_ occupe actuellement environ 2,9 To, avec environ 60 M de fichiers et de dossiers; parcourir simplement ces contenus prend du temps:

_## As Sudo (#), to avoid numerous "Permission denied" warnings:

time find /mnt/Backups/rsnapshot_backups | wc -l
60314138    ## 60.3M files, folders
34:07.30    ## 34 min

time du /mnt/Backups/rsnapshot_backups -d 0
3112240160  /mnt/Backups/rsnapshot_backups    ## 3.1 TB
33:51.88    ## 34 min

time rsnapshot du    ## << more accurate re: rsnapshot footprint
2.9T    /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G    /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G    /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T    total    ## 2.9 TB, per Sudo rsnapshot du (more accurate)
2:34:54          ## 2 hr 35 min
_

Ainsi, chaque fois que je dois rechercher un fichier sur ma partition _/_ (racine), je dois traiter (éviter si possible) de traverser ma partition de sauvegarde.


EXEMPLES

Parmi les différentes approches suggérées dans ce fil ( Comment exclure un répertoire dans find. Commande ), je trouve que les recherches utilisant la réponse acceptée sont beaucoup plus rapides - avec des mises en garde.

Solution 1

Supposons que je souhaite rechercher le fichier système _libname-server-2.a_, mais que je ne souhaite pas effectuer de recherche dans mes sauvegardes rsnapshot. Pour trouver rapidement un fichier système, utilisez le chemin d’exclusion _/mnt_ (c’est-à-dire, utilisez _/mnt_, pas _/mnt/_ ou _/mnt/Backups_ ou ...):

_## As Sudo (#), to avoid numerous "Permission denied" warnings:

time find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real    0m8.644s              ## 8.6 sec  <<< NOTE!
user    0m1.669s
 sys    0m2.466s

## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -Prune -o \
    -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
    TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec     ## ~3 sec  <<< NOTE!
_

... trouve ce fichier en quelques secondes seulement, alors que cela prend plus de temps (apparaissant de manière récurrente dans tous les répertoires "exclus" ):

_## As Sudo (#), to avoid numerous "Permission denied" warnings:

time find / -path /mnt/ -Prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real    33m10.658s            ## 33 min 11 sec (~231-663x slower!)
user    1m43.142s
 sys    2m22.666s

## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -Prune -o \
    -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
    TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec    ## 29.6 min
_

Solution 2

L’autre solution proposée dans ce fil ( SO # 4210042 ) fonctionne également mal:

_## As Sudo (#), to avoid numerous "Permission denied" warnings:

time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real    33m37.911s            ## 33 min 38 sec (~235x slower)
user    1m45.134s
 sys    2m31.846s

time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real    33m11.208s            ## 33 min 11 sec
user    1m22.185s
 sys    2m29.962s
_

SOMMAIRE | CONCLUSIONS

Utilisez l'approche illustrée dans " Solution 1 "

_find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
_

c'est à dire.

_... -path <excluded_path> -Prune -o ...
_

notant que chaque fois que vous ajoutez le _/_ final au chemin exclu, la commande find entre ensuite récursivement (dans tous) les répertoires _/mnt/*_ - qui, dans mon cas, sont dus au _/mnt/Backups/rsnapshot_backups/*_ __ sous-répertoires, contient en plus ~ 2.9 TB de fichiers à rechercher! Si vous n’ajoutez pas de _/_ final, la recherche doit s'achever presque immédiatement (en quelques secondes).

"Solution 2" (_... -not -path <exclude path> ..._) semble également effectuer une recherche récursive dans les répertoires exclus - en ne renvoyant pas les correspondances exclues, mais en consommant inutilement ce temps de recherche.


Recherche dans ces sauvegardes rsnapshot:

Pour rechercher un fichier dans l’une de mes sauvegardes horaires/quotidiennes/hebdomadaires/mensuelles rsnapshot:

_$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec   ## 5.2 minutes: despite apparent rsnapshot size
                            ## (~4 GB), it is in fact searching through ~2.9 TB)
_

Exclure un répertoire imbriqué:

Ici, je veux exclure un répertoire imbriqué, par exemple. _/mnt/Vancouver/projects/ie/claws/data/*_ lors de la recherche à partir de _/mnt/Vancouver/projects/_:

_$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97

$ time find . -path '*/data' -Prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07
_

Aside: L'ajout de _-print_ à la fin de la commande supprime l'impression du répertoire exclu:

_$ find / -path /mnt -Prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
_
3
Victoria Stuart

J'utilisais find pour fournir une liste de fichiers pour xgettext, et je voulais omettre un répertoire spécifique et son contenu. J'ai essayé beaucoup de permutations de -path combiné avec -Prune mais je n'ai pas pu exclure complètement le répertoire que je voulais supprimer.

Bien que j’ai pu ignorer le conten du répertoire que je voulais ignorer, find a ensuite renvoyé le répertoire lui-même parmi les résultats, ce qui a provoqué le blocage de xgettext. résultat (n'accepte pas les répertoires; seulement les fichiers).

Ma solution consistait simplement à utiliser grep -v pour ignorer le répertoire que je ne voulais pas dans les résultats:

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

Qu'il y ait ou non un argument pour find qui fonctionnera à 100%, je ne peux pas le dire avec certitude. Utiliser grep était une solution simple et rapide après un mal de tête.

3
Lemmings19
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -Prune
3

comment utiliser Prune-option-de-trouver-en-sh est une excellente réponse de Laurence Gonsalves sur le fonctionnement de -Prune.

Et voici la solution générique:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print

Pour éviter de saisir /path/to/seach/ plusieurs fois, entourez la find d'une paire pushd .. popd.

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd
2
go2null

Pour ce dont j'avais besoin, cela fonctionnait ainsi: trouver landscape.jpg sur tout le serveur à partir de la racine et exclure la recherche dans le répertoire /var:

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type d liste tous les d irectoires dans /

grep -v /var exclut `/ var 'de la liste

xargs -I '{}' find '{}' -name landscape.jpg exécute n'importe quelle commande, comme find avec chaque répertoire/résultat de la liste

2
adrianTNT

Cela me convient sur un Mac:

find . -name *.php -or -path "./vendor" -Prune -or -path "./app/cache" -Prune

Il exclura vendor et app/cache dir pour le nom de recherche qui a suffixé de php.

2
jiahut

Aucune des réponses précédentes n'est bonne sur Ubuntu. Essaye ça:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

J'ai trouvé ceci ici

2
sixro

Mieux vaut utiliser l'action exec que la boucle for:

find . -path "./dirtoexclude" -Prune \
    -o -exec Java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

Le exec ... '{}' ... '{}' \; sera exécuté une fois pour chaque fichier correspondant en remplaçant les accolades '{}' par le nom du fichier actuel.

Notez que les accolades sont entourées de guillemets simples pour les protéger de toute interprétation en tant que ponctuation de script Shell.*.


Remarques

* Extrait de la section EXEMPLES de la page de manuel find (GNU findutils) 4.4.2

1
Alberto

J'ai essayé la commande ci-dessus, mais aucun de ceux qui utilisent "-Prune" ne fonctionne pour moi. Finalement, j'ai essayé ceci avec la commande ci-dessous:

find . \( -name "*" \) -Prune -a ! -name "directory"
1
Jolly Liu

J'ai trouvé le nom des fonctions dans les fichiers sources C exclure * .o et exclure * .swp et exclure (fichier non standard) et exclure la sortie dir avec cette commande:

find .  \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
1
Ivan Ivanovich

Je ne sais pas si cela couvrirait tous les cas Edge, mais il serait très simple d'essayer ce qui suit:

ls -1|grep -v -e ddl -e docs| xargs rm -rf

Cela devrait supprimer tous les fichiers/répertoires du répertoire en cours excpet 'ddls' et 'docs'.

0
Arnab

Si les répertoires de recherche ont un motif (dans mon cas, la plupart du temps); vous pouvez simplement le faire comme ci-dessous:

find ./n* -name "*.tcl" 

Dans l'exemple ci-dessus; il recherche dans tous les sous-répertoires commençant par "n".

0
Prince Bhanwra

Pour les utilisateurs de FreeBSD :

 find . -name '*.js' -not -path '*exclude/this/dir*'
0
Richard Bartisek

Cela fonctionne parce que findTEST les fichiers pour le motif " * foo * ":

find ! -path "dir1" ! -path "dir2" -name "*foo*"

mais cela fonctionne PAS fonctionne si vous n'utilisez pas un motif (find ne fonctionne pas TEST le fichier) . Donc, find ne fait aucun usage de son ancien évalué " true " & " false "bools. Exemple de cas d'utilisation ne fonctionnant pas avec la notation ci-dessus:

find ! -path "dir1" ! -path "dir2" -type f

Il n'y a pas find TESTING! Donc, si vous avez besoin de trouver des fichiers sans correspondance de modèle, utilisez -Prune. De plus, l'utilisation de Prune find est toujours plus rapide, car il ignore réellement ces répertoires au lieu de les faire correspondre ou mieux ne les correspond pas. Donc, dans ce cas, utilisez quelque chose comme:

find dir -not \( -path "dir1" -Prune \) -not \( -path "dir2" -Prune \) -type f

ou:

find dir -not \( -path "dir1" -o -path "dir2" -Prune \) -type f

Cordialement

0
d0n

J'ai trouvé les suggestions sur cette page et de nombreuses autres pages ne fonctionnent tout simplement pas sur mon système Mac OS X. Cependant, j'ai trouvé une variante qui fonctionne pour moi.

L'idée principale est de rechercher le disque dur Macintosh en évitant de traverser tous les volumes externes, qui sont principalement des sauvegardes Time Machine, des sauvegardes d'image, des partages montés et des archives, mais sans avoir à les démonter tous, ce qui est souvent peu pratique.

Voici mon script de travail, que j'ai nommé "findit".

#!/usr/bin/env bash
# inspired by http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing. 
# However, logic is refactored because the Sobral version still traverses 
# everything on my system

echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter Sudo password if requested
Sudo find . -not \( \
-path ./Volumes/Archive -Prune -o \
-path ./Volumes/Boot\ OS\ X -Prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -Prune -o \
-path ./Volumes/jas -Prune -o \
-path ./Volumes/Recovery\ HD -Prune -o \
-path ./Volumes/Time\ Machine\ Backups -Prune -o \
-path ./Volumes/SuperDuper\ Image -Prune -o \
-path ./Volumes/userland -Prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$

Les différents chemins concernent les volumes d'archives externes, Time Machine, les machines virtuelles, les autres serveurs montés, etc. Certains noms de volume contiennent des espaces.

"Findit index.php" est un bon test, car ce fichier est présent à de nombreux endroits sur mon système. Avec ce script, il faut environ 10 minutes pour rechercher le disque dur principal. Sans ces exclusions, cela prend plusieurs heures.

0
Jeffrey Simon