web-dev-qa-db-fra.com

modèle `find -name` qui correspond à plusieurs modèles

J'essayais d'obtenir une liste de tous les fichiers python et html d'un répertoire avec la commande find Documents -name "*.{py,html}".

Puis vint la page de manuel:

Les accolades dans le modèle ('{}') ne sont pas considérées comme spéciales (c'est-à-dire que find. -Name 'foo {1,2}' correspond à un fichier nommé foo {1,2}, pas aux fichiers foo1 et foo2.

Comme cela fait partie d'une chaîne de communication, j'aimerais pouvoir spécifier les extensions auxquelles il correspond lors de l'exécution (pas de codage en dur). Si find ne peut tout simplement pas le faire, un Perl one-liner (ou similaire) conviendrait.

Edit: La réponse que j'ai finalement trouvée inclut toutes sortes de conneries, et est un peu longue aussi, alors je l'ai postée comme une réponse à la démangeaison originale que j'essayais de gratter. N'hésitez pas à le pirater si vous avez de meilleures solutions.

262
Xiong Chiamiov

Utilisez -o, ce qui signifie "ou":

find Documents \( -name "*.py" -o -name "*.html" \)

Edit : Désolé, relisez simplement la question ... vous auriez besoin de construire cette ligne de commande par programme, ce qui n'est pas si simple.

Utilisez-vous bash (ou Cygwin sous Windows)? Si vous êtes, vous devriez pouvoir faire ceci:

ls **/*.py **/*.html

qui pourrait être plus facile à construire par programme.

Edit : Commentaire @artbristol appliqué à la réponse. 

399
RichieHindle

Certaines éditions de find, principalement sur les systèmes Linux, éventuellement sur d’autres, prennent également en charge les options -regex et -regextype, qui permettent de rechercher des fichiers dont le nom correspond à l’expression régulière.

par exemple

find . -regextype posix-egrep -regex ".*\.(py|html)$" 

devrait faire l'affaire dans l'exemple ci-dessus . Cependant, il ne s'agit pas d'une fonction de recherche POSIX standard et dépend de la mise en œuvre.

48
intelekt

Vous pouvez ajouter par programme plus de clauses -name, séparées par -or:

find Documents \( -name "*.py" -or -name "*.html" \)

Ou optez plutôt pour une simple boucle:

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done
27
Stephan202

J'ai eu un besoin similaire. Cela a fonctionné pour moi:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -Prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print
10
bkidd

Cela trouvera tous les fichiers .c ou .cpp sur linux

$ find . -name "*.c" -o -name "*.cpp"

Vous n'avez pas besoin de la parenthèse échappée à moins de faire quelques mods supplémentaires. Ici, à partir de la page de manuel, ils disent que si le motif correspond, imprimez-le. Peut-être qu'ils essaient de contrôler l'impression. Dans ce cas, l’empreinte agit comme une condition et devient une condition "AND'd". Cela empêchera tous les fichiers .c d'être imprimés.

$ find .  -name "*.c" -o -name "*.cpp"  -print

Mais si vous aimez la réponse originale, vous pouvez contrôler l’impression. Cela trouvera également tous les fichiers .c.

$ find . \( -name "*.c" -o -name "*.cpp" \) -print
8
netskink
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done

simple mais fonctionne :)

2
mnrl

Je devais supprimer tous les fichiers dans les répertoires enfants, à l'exception de certains fichiers. Ce qui suit a fonctionné pour moi (trois modèles spécifiés):

find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +
1
Adobe
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"
1
user7531934

Qu'en est-il de

ls {*.py,*.html}

Il liste tous les fichiers se terminant par .py ou .html dans leurs noms de fichiers

0
Dr_Hope

Des accolades dans le motif \(\) sont nécessaires pour nommer le motif avec or

find Documents -type f \( -name "*.py" -or -name "*.html" \)

Alors que pour le modèle de nom avec l'opérateur and, il n'est pas nécessaire

find Documents -type f ! -name "*.py" -and ! -name "*.html" 
0
Chetabahana

Cela fonctionne sur AIX Korn Shell.

find *.cbl *.dms -Prune -type f -mtime -1

Ceci recherche *.cbl ou *.dms qui ont 1 jour, dans le répertoire courant seulement, en sautant les sous-répertoires.

0
Abdul M Gill