Eu sei que posso encontrar arquivos usando find
: find . -type f -name 'sunrise'
. Exemplo de resultado:
./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise
Também sei que posso determinar o tipo de arquivo de um arquivo: file sunrise
. Exemplo de resultado:
sunrise: PEM RSA private key
Mas como posso encontrar arquivos por tipo de arquivo?
Por exemplo, my-find . -type f -name 'sunrise' -filetype=bash-script
:
./astronomy/sunrise
./schedule/sunrise
"Tipos de arquivo" em um sistema Unix são coisas como arquivos regulares, diretórios, pipes nomeados, arquivos especiais de caracteres, links simbólicos etc. Esses são os tipos de arquivos que
find
podem ser filtrados com sua-type
opção.O
find
utilitário por si só não pode distinguir entre um "script de shell", "arquivo de imagem JPEG" ou qualquer outro tipo de arquivo normal . Esses tipos de dados podem, no entanto, ser diferenciados pelofile
utilitário, que analisa assinaturas específicas dentro dos próprios arquivos para determinar seu tipo.Uma maneira comum de rotular os diferentes tipos de arquivos de dados é pelo tipo MIME e
file
é capaz de determinar o tipo MIME de um arquivo.Usando
file
withfind
para detectar o tipo MIME de arquivos regulares e use-o para encontrar apenas scripts de shell:ou, usando
bash
,Adicione
-name sunrise
antes do-exec
se desejar detectar apenas scripts com esse nome.O
find
comando acima encontrará todos os arquivos regulares dentro ou abaixo do diretório atual e, para cada um desses arquivos, chamará um script de shell curto em linha. Esse script é executadofile -bi
no arquivo encontrado e sai com um status de saída zero se a saída desse comando contiver a string/x-shellscript
. Se a saída não contiver essa string, ela sairá com um status de saída diferente de zero, o que fará com quefind
continue imediatamente com o próximo arquivo. Se o arquivo for um script de shell, ofind
comando prosseguirá para gerar o nome do caminho do arquivo (o-print
no final, que também pode ser substituído por alguma outra ação).O
file -bi
comando produzirá o tipo MIME do arquivo. Para um script de shell no Linux (e na maioria dos outros sistemas), isso seria algo comoenquanto em sistemas com uma variante um pouco mais antiga do
file
utilitário, pode serO bit comum é a
/x-shellscript
substring.Observe que no macOS, você teria que usar
file -bI
em vez defile -bi
por motivos (a-i
opção faz algo bem diferente). A saída no macOS é semelhante à de um sistema Linux.Você gostaria de executar alguma ação personalizada em cada script de shell encontrado, você poderia fazer isso com outro
-exec
no lugar dos-print
comandosfind
acima, mas também seria possível fazerou, com
bash
,Relacionado:
Você pode executar
file
em cada arquivo encontrado e, em seguida, grep para o resultado em que está interessado.Sugiro tornar o padrão de pesquisa o mais próximo possível de sua expectativa para manter baixo o número de correspondências de falsos positivos.
Esteja ciente de que arquivos com novas linhas em seus nomes de arquivo podem causar problemas com essa abordagem.
Uma forma mais curta que não envolve tanta magia de shell:
find . -exec sh -c "file '{}' | grep -q 'pattern'" \; -print
Usando
perl
oFile::LibMagic
módulo de:File::LibMagic
usa os mesmos algoritmos e banco de heurísticas para adivinhar o tipo de arquivo quefile
, mas aqui como tudo é feito em umaperl
invocação, é muito mais eficiente do que ter que executar umafile
invocação para cada arquivo.Não tenho certeza se é isso que se procura, mas: Assim?
find DIRECTORY -name "*.EXT" -type f -exec COMMAND {} \;
Onde você substitui:
Por exemplo, calcule a soma sha512 em todos os arquivos com a extensão .odt, dentro do diretório Docs/: