web-dev-qa-db-fra.com

Utiliser la commande find mais exclure les fichiers de deux répertoires

Je souhaite rechercher les fichiers se terminant par _peaks.bed, mais exclure les fichiers des dossiers tmp et scripts.

Ma commande est comme ça:

 find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)

Mais ça n'a pas marché. Les fichiers des dossiers tmp et script seront toujours affichés.

Est-ce que quelqu'un a des idées à ce sujet?

77
Hanfei Sun

Voici comment vous pouvez spécifier cela avec find:

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

Explication:

  • find . - Commence une recherche dans le répertoire de travail en cours (récursivement par défaut)
  • -type f - Spécifiez à find que vous ne voulez que des fichiers dans les résultats
  • -name "*_peaks.bed" - Recherche les fichiers dont le nom se termine par _peaks.bed
  • ! -path "./tmp/*" - Exclure tous les résultats dont le chemin commence par ./tmp/
  • ! -path "./scripts/*" - exclut également tous les résultats dont le chemin commence par ./scripts/

Test de la solution:

$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"

./d/4
./c/3
./e/a
./e/b
./e/5

Vous étiez assez proche, l'option -name ne considère que le nom de base, alors que -path considère le chemin complet =)

173
sampson-chen

Voici une façon de le faire ...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
8
alex

Essayez quelque chose comme

find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -Prune \)

et ne soyez pas trop surpris si je me suis un peu trompé. Si l'objectif est un exec (au lieu de print), substituez-le simplement à la place.

0
DrC

pour moi, cette solution n'a pas fonctionné sur un exec de commande avec find, je ne sais pas vraiment pourquoi, alors ma solution est

find . -type f -path "./a/*" -Prune -o -path "./b/*" -Prune -o -exec gzip -f -v {} \;

Explication: identique à sampson-chen un avec les ajouts de

-Prune - ignore le chemin d'accès de ...

-o - Si les résultats ne correspondent pas, imprimez les résultats, (nettoyez les répertoires et imprimez les résultats restants)

18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -Prune -o -path "./b/*" -Prune -o -exec gzip -f -v {} \;

gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3:    0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4:    0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5:    0.0% -- replaced with ./e/5.gz
./e/a:    0.0% -- replaced with ./e/a.gz
./e/b:    0.0% -- replaced with ./e/b.gz
0
Al3x

Vous pouvez essayer ci-dessous:

find ./ ! \( -path ./tmp -Prune \) ! \( -path ./scripts -Prune \) -type f -name '*_peaks.bed'
0
Jacky Jiang