Existe-t-il un moyen simple de rechercher de manière récursive tous les fichiers d'une hiérarchie de répertoires qui ne se terminent pas dans une liste d'extensions? Par exemple. tous les fichiers qui ne sont pas * .dll ou * .exe
La recherche UNIX/GNU, aussi puissante soit-elle, ne semble pas avoir un 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 correspond pas à une expression particulière.
Je suis dans un environnement Windows (en utilisant le port GnuWin32 de la plupart des outils GNU), je suis donc également ouvert aux solutions exclusivement Windows.
Ou sans (
et le besoin 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
find . ! \( -name "*.exe" -o -name "*.dll" \)
$ find . -name \*.exe -o -name \*.dll -o -print
Les deux premières options -name n'ont pas d'option -print, elles ont donc été ignorées. Tout le reste est imprimé.
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 éléments qui ne pas = correspondent à cette expression".
un de plus :-)
$ ls -ltr total 10 - rw-r - r-- 1 scripteur linuxdumb 47 déc 23 14:46 test1 - rw-r - r-- 1 scripteur linuxdumb 0 4 janvier 23h40 test4 - rw-r - r-- 1 scripteur linuxdumb 0 4 janvier 23:40 test3 - rw-r - r-- 1 scripteur linuxdumb 0 4 janvier 23h40 test2 - rw-r - r-- 1 scripteur linuxdumb 0 janvier 4 23:41 file5 - rw-r - r-- 1 scripteur linuxdumb 0 janvier 4 23:41 file4 - rw-r - r-- 1 scripteur linuxdumb 0 janvier 4 23:41 file3 - rw-r - r-- 1 scripteur linuxdumb 0 janvier 4 23 : 41 fichier2 - rw-r - r-- 1 scripteur linuxdumb 0 janvier 4 23:41 fichier1 $ Find. -type f! -name "* 1"! -name "* 2" -print ./ test3 ./ test4 ./ fichier3 ./ fichier4 ./ fichier5 $
Linux/OS X:
À partir du répertoire en cours, recherchez tous les fichiers se terminant par .dll ou .exe de manière récursive.
find . -type f | grep -P "\.dll$|\.exe$"
À partir du répertoire en cours, recherchez tous les fichiers ne se terminant PAS par .dll ou .exe de manière récursive.
find . -type f | grep -vP "\.dll$|\.exe$"
Remarques:
(1) L'option P dans 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'exécuter la commande grep conjointement avec des expressions régulières, je trouve que le style Perl est le style le plus puissant qui soit.
(2) L’option v de grep demande au shell d’exclure tout fichier répondant à l’expression régulière
(3) Le caractère $ à la fin de say ".dll $" 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".
find /data1/batch/source/export -type f -not -name "*.dll" -not -name "*.exe"
Les autres solutions de cette page ne sont pas souhaitables si la liste des extensions est longue. Conserver 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 que la liste des extensions est construit 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é un répertoire et une structure 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 ça:
## 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\)"
Ce qui résulte en:
./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 changer le bloc de code.
NOTE ne fonctionne pas avec OSX natif find
- utilisez plutôt gnu find.