Encontre arquivos filtrados por várias extensões

43

Qual é a sintaxe correta para:

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

Isso funciona, mas é deselegante:

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

Como fazer o mesmo, mas em menos pressionamentos de teclas?

    
por Dave Jarvis 01.04.2010 / 03:31

4 respostas

62

Você pode combinar diferentes expressões de pesquisa com os operadores lógicos -or ou -and , para que seu caso possa ser escrito como

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

Isso também mostra que você não precisa escapar de caracteres de shell especiais ao usar aspas.

Editar

Como -or tem precedência menor do que a parte implícita do -and entre -type e o primeiro -name colocar o nome entre parênteses, como sugerido por Chris.

    
por 01.04.2010 / 03:35
14

Aqui está uma maneira de fazer sua primeira versão:

find -type f -regex ".*/.*\.\(shtml\|css\)"
    
por 01.04.2010 / 03:57
7

Você precisa criar um parênteses para incluir apenas arquivos:

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

Bônus : esta é a sintaxe compatível com POSIX.

    
por 01.04.2010 / 08:31
3

Muitas vezes, acabo usando egrep, ou pipes maiores, ou perl para filtros ainda mais complexos:

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

Pode ser um pouco menos eficiente, mas isso geralmente não é uma preocupação, e para coisas mais complexas, geralmente é mais fácil de construir e modificar.

A advertência padrão se aplica a não usar isso para arquivos com nomes de arquivos estranhos (por exemplo, contendo novas linhas).

    
por 01.04.2010 / 18:41