Como posso obter a (s) extensão (ões) de um arquivo com base em seu conteúdo?

0

Estou planejando fazer o download de várias imagens de um site que não vêm com uma extensão, por isso quero adicionar uma com base no conteúdo do arquivo ou no tipo MIME.

file <filename> faz um ótimo trabalho ao identificar o tipo de arquivo, mas eu preciso da extensão.

--extension
      Print a slash-separated list of valid extensions for the file type found.

Esta é a página man do file , mas parece não funcionar:

$ file --extension test_text_file.txt
test_text_file.txt: ???

$ file --extension test_png_file.png
test_png_file.png: ???

$ file --extension test_gif_file.gif
test_gif_file.gif: ???

Ele literalmente imprime ??? para cada arquivo que eu passar para ele, mesmo aqueles que já possuem uma extensão adequada. Todos esses são arquivos válidos de seus tipos e são reconhecidos perfeitamente por file sem --extension .

Por que file --extension não funciona para mim e o que posso usar para obter a extensão de um arquivo?

Uma ideia seria usar file --mime-type e, em seguida, criar uma matriz de tabela de distribuição que mapeie tipos mime conhecidos para suas extensões, mas prefiro ter uma solução mais simples e segura.

    
por confetti 09.08.2018 / 02:43

1 resposta

1

Why does file --extension not work for me?

Não só para você. Veja esta questão . Um dos comentários parece certo:

Maybe just a very, very incomplete feature?

Eu não encontrei nenhuma ferramenta Unix padrão para fazer a conversão, então sua ideia pode ser a solução mais fácil de qualquer maneira.

An idea would be to use file --mime-type and then create a dispatch table array that maps known mime-types to their extensions, but I'd much rather have a simpler and safer solution.

Observe que esse mapa existe, é /etc/mime.types . Veja essa outra pergunta no Unix & Linux SE . Com base em uma das respostas, desenvolvi a seguinte função:

function getext() {
   [ "$#" != 1 ] && { echo "Wrong number of arguments. Provide exactly one." >&2; return 254; }
   [ -r "$1" ] || { echo "Not a file, nonexistent or unreadable." >&2; return 1; }
   grep "^$(file -b --mime-type "$1")"$'\t' /etc/mime.types |
      awk -F '\t+' '{print $2}'
}

Uso:

getext test_text_file.txt   # it takes just one argument

Adapte-o às suas necessidades, crie um roteiro, etc. As principais preocupações:

  • Se for bem-sucedida (status de saída 0 ), a saída pode não estar vazia ou vazia (nem mesmo \n ).
  • Alguns tipos MIME retornam mais de uma extensão. Você pode usar cut -d ' ' -f 1 para obter no máximo um, mas pode não ser o que você quer.
  • Portanto, um arquivo de mapeamento personalizado em vez de /etc/mime.types pode ser útil. Este comando mostrará quais tipos mime existem no diretório atual (e subdiretórios):

    find . -type f -exec file -b --mime-type {} + | sort | uniq
    
  • grep não deve corresponder mais de uma vez (pelo menos com /etc/mime.types ); ^ (início da linha) e $'\t' (tabulação) existem para evitar correspondência parcial. Use grep -m 1 ... (ou head -n 1 depois) para ter certeza de obter no máximo uma linha.

por 13.08.2018 / 09:43