UNIX find pour trouver des noms de fichiers ne se terminant pas par des extensions spécifiques?

Existe-t-il un moyen simple de trouver récursivement tous les fichiers d'une hiérarchie de répertoires, qui ne se terminent pas par une liste d'extensions? Par exemple, tous les fichiers qui ne sont pas *.dll ou *.exe

Unix / GNU find, aussi puissant soit-il, ne semble pas avoir de mode exclude (ou il me manque), et j'ai toujours eu du mal à utiliser des expressions régulières pour trouver des choses qui ne correspondent pas à une expression particulière.

Je suis dans un environnement Windows (en utilisant le port GnuWin32 de la plupart des GNU outils), donc je suis également ouvert pour les solutions Windows uniquement.

163
demandé sur Jeff Ferland 2009-08-27 18:24:45

8 réponses

Ou sans ( et la nécessité d'y échapper:

find . -not -name "*.exe" -not -name "*.dll"

Et d'exclure également la liste des répertoires

find . -not -name "*.exe" -not -name "*.dll" -not -type d

Ou en logique positive ;-)

find . -not -name "*.exe" -not -name "*.dll" -type f
272
répondu Hardy 2012-06-12 16:37:14
find . ! \( -name "*.exe" -o -name "*.dll" \)
41
répondu Chen Levy 2009-08-27 14:28:55
$ find . -name \*.exe -o -name \*.dll -o -print

Les deux premières options de nom n'ont pas d'option d'impression, elles ont donc sauté. Tout le reste est imprimé.

7
répondu Jeff Ferland 2009-08-27 14:29:59

Vous pouvez faire quelque chose en utilisant la commande grep:

find . | grep -v '(dll|exe)$'

Le drapeau -v sur grep signifie spécifiquement " trouver des choses qui ne correspondent pas à cette expression."

4
répondu VoteyDisciple 2015-08-10 13:30:50

Un de plus :-)

$ ls -ltr
total 10
-rw-r--r--    1 scripter     linuxdumb         47 Dec 23 14:46 test1
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:40 test4
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:40 test3
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:40 test2
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:41 file5
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:41 file4
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:41 file3
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:41 file2
-rw-r--r--    1 scripter     linuxdumb          0 Jan  4 23:41 file1
$ find . -type f ! -name "*1" ! -name "*2" -print
./test3
./test4
./file3
./file4
./file5
$

Référence de commande unix find

2
répondu logic 2010-01-04 21:52:46

Linux / OS X:

À partir du répertoire courant, recherchez récursivement tous les fichiers se terminant par .dll ou .exe

find . -type f | grep -P "\.dll$|\.exe$"

À partir du répertoire courant, recherchez récursivement tous les fichiers qui ne se terminent pas .dll ou .exe

find . -type f | grep -vP "\.dll$|\.exe$"

Notes:

(1) L'option P sur grep indique que nous utilisons le style Perl pour écrire nos expressions régulières à utiliser conjointement avec la commande grep. Dans le but d'excécuter la commande grep dans en conjonction avec les expressions régulières, je trouve que le style Perl est le style le plus puissant autour.

(2) l'option v sur grep indique au shell d'exclure tout fichier qui satisfait l'expression régulière

(3) le caractère $ à la fin de say ".dell$" est un caractère de contrôle de délimiteur qui indique au shell que la chaîne de nom de fichier se termine par ".dll "

1
répondu Vietnhi Phuvan 2014-03-10 16:51:37

D'autres solutions sur cette page ne sont pas souhaitables si vous avez une longue liste d'extensions-maintenir une longue séquence de -not -name 'this' -not -name 'that' -not -name 'other' serait fastidieux et sujet aux erreurs-ou si la recherche est programmatique et la liste des extensions est construite au moment de l'exécution.

Pour ces situations, une solution qui sépare plus clairement les données (la liste des extensions) et le code (les paramètres à find) peut être souhaitable. Étant donné une structure de répertoire et de fichier qui ressemble à ceci:

.
└── a
    ├── 1.txt
    ├── 15.xml
    ├── 8.dll
    ├── b
    │   ├── 16.xml
    │   ├── 2.txt
    │   ├── 9.dll
    │   └── c
    │       ├── 10.dll
    │       ├── 17.xml
    │       └── 3.txt
    ├── d
    │   ├── 11.dll
    │   ├── 18.xml
    │   ├── 4.txt
    │   └── e
    │       ├── 12.dll
    │       ├── 19.xml
    │       └── 5.txt
    └── f
        ├── 13.dll
        ├── 20.xml
        ├── 6.txt
        └── g
            ├── 14.dll
            ├── 21.xml
            └── 7.txt

Vous pouvez faire quelque chose comme ceci:

## data section, list undesired extensions here
declare -a _BADEXT=(xml dll)

## code section, this never changes
BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed 's/|/\\|/g' )"
find . -type f ! -regex ".*\.\($BADEXT\)"

, Qui se traduit par:

./a/1.txt
./a/b/2.txt
./a/b/c/3.txt
./a/d/4.txt
./a/d/e/5.txt
./a/f/6.txt
./a/f/g/7.txt

Vous pouvez modifier la liste des extensions sans modifier le bloc de code.

NOTE ne fonctionne pas avec OSX natif find - utilisez gnu find à la place.

0
répondu Chris Johnson 2015-07-16 17:37:25
find  /data1/batch/source/export   -type f -not  -name "*.dll" -not -name "*.exe"
0
répondu gwecho huang 2018-03-02 04:21:15