O fator chave para alcançar find enlightenment;) é:
find's business is evaluating expressions -- not locating files. Yes,findcertainly locates files; but that's really just a side effect.
Existe uma abordagem alternativa a essa questão que vale a pena conhecer (como também descrito em Unix Power Tools, na seção " Usando -exec para criar testes personalizados "):
find . -type f -exec sh -c 'file -b "$1" | grep -iqE "^ELF|^C source"' sh {} \; -print
Vale a pena conhecer esse método de filtragem, já que ele pode ser usado para muitas outras coisas além de simplesmente imprimir o nome do arquivo; apenas mude o operador -print para qualquer outro operador que você gostar (incluindo outro operador -exec ) e faça o que quiser com ele.
Existe uma desvantagem de desempenho para este comando (que também está presente em a outra resposta ), que é que, como estamos usando \; e não + , estamos gerando um shell para cada arquivo. Usar + para passar vários arquivos de uma vez para o comando sh e processá-los com um loop for fornece uma vantagem perceptível de desempenho:
find . -exec sh -c 'for f do file -b "$f" | grep -qE "^ELF|^C source" && printf %s\n "$f"; done' sh {} +
Você pode ver a comparação para si mesmo executando os dois comandos a seguir e comparando a saída de time :
time find . -exec sh -c 'for f do file -b "$f" | grep -qE "^ELF|^C source" && printf %s\n "$f"; done' sh {} +
time find . -exec sh -c 'file -b "$1" | grep -qE "^ELF|^C source" && printf %s\n "$1"' sh {} \;
O ponto real, no entanto, é:
Nunca execute um loop for do shell em uma lista de arquivos com saída de find . Em vez disso, execute a ação que você precisa fazer em cada arquivo diretamente em find de usando o operador -exec , ou embed um shell for loop dentro de um comando find e faça desta forma.
Algumas razões adicionais: