Modèle `find -name` correspondant à plusieurs modèles

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

Puis vint la page de manuel:

Les accolades dans le motif (‘{}’) ne sont pas considérées comme spéciales (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 production, je voudrais pouvoir spécifier les extensions auxquelles il correspond au moment de l’exécution (pas de codage en dur). Si trouver 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 elle est un peu longue aussi, alors je l’ai affichée comme une réponse à la question initiale que j’essayais de rayer. N’hésitez pas à hacher cela si vous avez de meilleures solutions.

    Utilisez -o , qui signifie “ou”:

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

    Edit : Désolé, relisez simplement la question … vous aurez besoin de construire cette ligne de commande par programmation, ce qui n’est pas si simple.

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

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

    ce qui pourrait être plus facile à construire par programmation.

    Edit : Applique le commentaire @artbristol à la réponse.

    Certaines éditions de find, principalement sur les systèmes Linux, éventuellement sur d’autres, supportent également les options -regex et -regextype, qui trouvent des fichiers avec des noms correspondant à la regex.

    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 l’implémentation.

    Vous pouvez append par programmation des clauses -name séparées par -or :

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

    Ou bien optez pour une simple boucle à la place:

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

    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 

    Ceci 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 sauf si vous faites des mods supplémentaires. Ici, à partir de la page de manuel, ils disent si le motif correspond, imprimez-le. Peut-être essaient-ils de contrôler l’impression. Dans ce cas, -print agit comme un conditionnel et devient un conditionnel “AND’d”. Cela empêchera l’impression de fichiers .c.

     $ 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 

    Mon défaut a été:

    find -type f | egrep -i "*.java|*.css|*.cs|*.sql"

    Comme le moins de processus, l’exécution exécutée par Brendan Long et Stephan202 et al .:

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

     #! /bin/bash filetypes="*.py *.xml" for type in $filetypes do find Documents -name "$type" done 

    simple mais fonctionne 🙂

    Je devais supprimer tous les fichiers dans les répertoires enfants, à l’exception de certains fichiers. Les éléments suivants ont 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 '{}' + 
     find MyDir -iname "*.[j][p][g]" + find MyDir -iname "*.[b][m][p]" = find MyDir -iname "*.[jb][pm][gp]" 

    Cela fonctionne sur AIX korn shell.

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

    Ceci recherche les *.cbl ou *.dms qui ont 1 jour, dans le répertoire actuel uniquement, en ignorant les sous-répertoires.