web-dev-qa-db-fra.com

Trouver des fichiers filtrés par plusieurs extensions

Quelle est la syntaxe correcte pour:

find . -type f -name \*.\(shtml\|css\)

Cela fonctionne, mais est inélégant:

find . -type f -name \*.shtml > f.txt && find . -type f -name \*.css >> f.txt

Comment faire la même chose, mais en moins de frappe?

50
Dave Jarvis

Vous pouvez combiner différentes expressions de recherche avec les opérateurs logiques -or ou -and, afin que votre cas puisse être écrit de la manière suivante:

find . -type f \( -name "*.shtml" -or -name "*.css" \)

Cela montre également que vous n'avez pas besoin d'échapper à des caractères spéciaux du shell lorsque vous utilisez des guillemets.

Modifier

Étant donné que -or a une priorité inférieure à celle implicite -and entre -type et le premier -name, mettez la partie du nom entre parenthèses comme suggéré par Chris.

70
Benjamin Bannier

Voici une façon de faire votre première version:

find -type f -regex ".*/.*\.\(shtml\|css\)"
15
Dennis Williamson

Vous devez mettre entre parenthèses uniquement les fichiers:

find . -type f \( -name "*.shtml" -o -name "*.css" \) -print

Bonus : il s'agit d'une syntaxe compatible POSIX.

11
Teddy

Je me retrouve souvent à utiliser des tubes egrep ou plus longs, ou Perl pour des filtres encore plus complexes:

find . -type f | egrep '\.(shtml|css)$'
find . -type f | Perl -lne '/\.shtml|\.css|page\d+\.html$/ and print'

C'est peut-être un peu moins efficace, mais ce n'est généralement pas un problème. Pour des choses plus complexes, il est généralement plus facile à construire et à modifier.

L'avertissement standard concerne le fait de ne pas utiliser ceci pour les fichiers portant des noms de fichiers étranges (contenant par exemple des nouvelles lignes).

4
reinierpost