AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 483871
Accepted
Flux
Flux
Asked: 2018-11-25 06:43:45 +0800 CST2018-11-25 06:43:45 +0800 CST 2018-11-25 06:43:45 +0800 CST

Como encontrar arquivos por tipo de arquivo?

  • 772

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
files find
  • 5 5 respostas
  • 63412 Views

5 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2018-11-25T07:17:56+08:002018-11-25T07:17:56+08:00

    "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 findpodem ser filtrados com sua -typeopção.

    O findutilitá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 pelo fileutilitá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 filewith findpara detectar o tipo MIME de arquivos regulares e use-o para encontrar apenas scripts de shell:

    find . -type f -exec sh -c '
        case $( file -bi "$1" ) in (*/x-shellscript*) exit 0; esac
        exit 1' sh {} \; -print
    

    ou, usando bash,

    find . -type f -exec bash -c '
        [[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} \; -print
    

    Adicione -name sunriseantes do -execse desejar detectar apenas scripts com esse nome.

    O findcomando 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 é executado file -bino 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 que findcontinue imediatamente com o próximo arquivo. Se o arquivo for um script de shell, o findcomando prosseguirá para gerar o nome do caminho do arquivo (o -printno final, que também pode ser substituído por alguma outra ação).

    O file -bicomando produzirá o tipo MIME do arquivo. Para um script de shell no Linux (e na maioria dos outros sistemas), isso seria algo como

    text/x-shellscript; charset=us-ascii
    

    enquanto em sistemas com uma variante um pouco mais antiga do fileutilitário, pode ser

    application/x-shellscript
    

    O bit comum é a /x-shellscriptsubstring.

    Observe que no macOS, você teria que usar file -bIem vez de file -bipor motivos (a -iopçã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 -execno lugar dos -printcomandos findacima, mas também seria possível fazer

    find . -type f -exec sh -c '
        for pathname do
            case $( file -bi "$pathname" ) in
                */x-shellscript*) ;;
                *) continue
            esac
    
            # some code here that acts on "$pathname"
    
        done' sh {} +
    

    ou, com bash,

    find . -type f -exec bash -c '
        for pathname do
            [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue
    
            # some code here that acts on "$pathname"
    
        done' bash {} +
    

    Relacionado:

    • Entendendo a opção -exec de `find`
    • 29
  2. Rolf
    2018-11-30T06:01:53+08:002018-11-30T06:01:53+08:00

    Você pode executar fileem cada arquivo encontrado e, em seguida, grep para o resultado em que está interessado.

    # When looking for ASCII Text
    find . -type f -exec file {} \; | grep "ASCII"
    # or for MS Word Documents
    find . -type f -exec file {} \; | grep "Microsoft Word"
    

    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.

    • 2
  3. zbyszek
    2022-02-12T07:01:42+08:002022-02-12T07:01:42+08:00

    Uma forma mais curta que não envolve tanta magia de shell:

    find . -exec sh -c "file '{}' | grep -q 'pattern'" \; -print

    • 2
  4. Stéphane Chazelas
    2018-11-25T14:08:12+08:002018-11-25T14:08:12+08:00

    Usando perlo File::LibMagicmódulo de:

    perl -MFile::LibMagic=:easy -MFile::Find -le '
      find sub {
        print $File::Find::name if
          $_ eq "sunrise" and
          -f and
          MagicFile$_ eq "PEM RSA private key"
      }, @ARGV' -- .
    

    File::LibMagicusa os mesmos algoritmos e banco de heurísticas para adivinhar o tipo de arquivo que file, mas aqui como tudo é feito em uma perlinvocação, é muito mais eficiente do que ter que executar uma fileinvocação para cada arquivo.

    • 0
  5. William Martens
    2021-03-13T08:22:23+08:002021-03-13T08:22:23+08:00

    Não tenho certeza se é isso que se procura, mas: Assim?

    find DIRECTORY -name "*.EXT" -type f -exec COMMAND {} \;

    Onde você substitui:

    DIRETÓRIO com o diretório para procurar arquivos em (e, opt. Operar em)

    -name "*.EXT" é a extensão, *curinga significa tudo, então tudo que termina em "EXT" (, *todo arquivo que termina com extensão

    EXT*)

    -type f é , arquivo. (tipo arquivo, não diretório, por exemplo)

    -exec COMMAND está executando COMMAND em cada arquivo encontrado com a extensão EXT no final deles.

    Por exemplo, calcule a soma sha512 em todos os arquivos com a extensão .odt, dentro do diretório Docs/:

    find Docs/ -name "*.odt" -type f -exec sha512sum {} \;
    
    • 0

relate perguntas

  • verificando se existe uma pasta em determinado diretório

  • Localizar e substituir cores em arquivos CSS na linha de comando

  • Como encontrar tipos de arquivos específicos e tar-los?

  • GNU find: obtenha caminho absoluto e relativo em -exec

  • du/df e ls relatando diferentes usos de disco

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve