Comment puis-je obtenir les extensions d'un fichier en fonction de son contenu?

0

Je prévois de télécharger une série d’images d’un site Web qui ne viennent pas avec une extension. Je souhaite donc en ajouter une en fonction du contenu du fichier ou du type MIME.

file <filename> fait un excellent travail pour identifier le type de fichier, mais j'ai besoin de l'extension.

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

C'est de la part de file La page de manuel de, mais cela ne semble pas fonctionner:

$ 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: ???

Il imprime littéralement ??? pour chaque fichier que j'y passe, même ceux qui ont déjà une extension appropriée. Ce sont tous des fichiers valides de leurs types et sont parfaitement reconnus par file sans pour autant --extension.

Pourquoi file --extension ne fonctionne pas pour moi et que puis-je utiliser pour obtenir une extension de fichier?

Une idée serait d'utiliser file --mime-type puis créez un tableau de tableau de répartition qui mappe les types MIME connus avec leurs extensions, mais je préférerais de loin une solution plus simple et plus sûre.

confetti
la source
Je suppose que vous avez essayé de supprimer l’extension du nom de fichier puis que vous avez exécuté file encontre?
Appleoddity
Oui. La sortie est la même ??? pour chaque fichier.
confetti
Quelle est votre version de fichier? fichier --version
cybernard
@cybernard file-5.33
confetti

Réponses:

1

Pourquoi file --extension ne fonctionne pas pour moi?

Pas seulement pour toi. Voir cette question . Un des commentaires semble juste:

Peut-être juste une fonctionnalité très, très incomplète?

Je n'ai trouvé aucun outil Unix standard pour effectuer la conversion, votre idée peut donc être la solution la plus simple.

Une idée serait d'utiliser file --mime-type puis créez un tableau de tableau de répartition qui mappe les types MIME connus avec leurs extensions, mais je préférerais de loin une solution plus simple et plus sûre.

Notez qu'une telle carte existe, c'est /etc/mime.types. Voir cette autre question sur Unix & amp; SE Linux . En me basant sur l’une des réponses, j’ai eu la fonction suivante:

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}'
}

Usage:

getext test_text_file.txt   # it takes just one argument

Adaptez-le à vos besoins, faites-en un script, etc. Les principales préoccupations sont les suivantes:

  • Si réussi (statut de sortie) 0 ), la sortie peut être non vide ou vide (même pas \n ).
  • Certains types MIME renvoient plus d'une extension. Vous pouvez utiliser cut -d ' ' -f 1 pour en avoir au plus un, ce n'est peut-être pas celui que vous voulez.
  • Donc, un fichier de carte personnalisé au lieu de /etc/mime.types peut être utile. Cette commande vous montrera quels types mime existent dans le répertoire courant (et les sous-répertoires):

    find . -type f -exec file -b --mime-type {} + | sort | uniq
    
  • grep ne doit pas correspondre plus d'une fois (au moins avec /etc/mime.types ) ^ (début de ligne) et $'\t' (onglet) sont là pour éviter la correspondance partielle. Utilisation grep -m 1 ... (ou head -n 1 plus tard) pour être sûr que vous obtiendrez au plus une ligne.

Kamil Maciorowski
la source
Merci beaucoup pour cette excellente réponse et le soupçon de /etc/mime.types, cela fonctionne parfaitement pour moi.
confetti