Wie kann ich die Erweiterung(en) einer Datei anhand ihres Inhalts ermitteln?

Wie kann ich die Erweiterung(en) einer Datei anhand ihres Inhalts ermitteln?

Ich habe vor, eine Reihe von Bildern von einer Website herunterzuladen, die keine Erweiterung haben. Daher möchte ich basierend auf dem Inhalt oder MIME-Typ der Datei eine hinzufügen.

file <filename>erkennt den Dateityp sehr gut, ich brauche allerdings die Erweiterung.

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

Dies stammt von fileder Manpage von, scheint aber nicht zu funktionieren:

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

Es druckt buchstäblich ???für jede Datei, die ich ihm übergebe, auch für die, die bereits eine richtige Erweiterung haben. Alle diese Dateien sind gültige Dateien ihres Typs und werden von fileohne perfekt erkannt --extension.

Warum file --extensionfunktioniert es bei mir nicht und was kann ich verwenden, um die Erweiterung einer Datei zu erhalten?

Eine Idee wäre, file --mime-typeein Dispatch-Tabellenarray zu verwenden und dann zu erstellen, das bekannte MIME-Typen ihren Erweiterungen zuordnet, aber ich hätte lieber eine einfachere und sicherere Lösung.

Antwort1

Warum file --extensionfunktioniert es bei mir nicht?

Nicht nur für dich. Siehediese Frage. Einer der Kommentare dort scheint richtig zu sein:

Vielleicht nur eine sehr, sehr unvollständige Funktion?

Ich habe kein Standard-Unix-Tool für die Konvertierung gefunden, daher ist Ihre Idee möglicherweise sowieso die einfachste Lösung.

Eine Idee wäre, file --mime-typeein Dispatch-Tabellenarray zu verwenden und dann zu erstellen, das bekannte MIME-Typen ihren Erweiterungen zuordnet, aber ich hätte lieber eine einfachere und sicherere Lösung.

Beachten Sie, dass eine solche Karte existiert. Sie ist /etc/mime.types. Siehedies ist eine weitere Frage zu Unix und Linux SE. Basierend auf einer der Antworten habe ich die folgende Funktion entwickelt:

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

Verwendung:

getext test_text_file.txt   # it takes just one argument

Passen Sie es Ihren Bedürfnissen an, machen Sie ein Skript daraus usw. Die wichtigsten Anliegen:

  • Bei Erfolg (Beendigungsstatus 0), kann die Ausgabe nicht leer oder leer (nicht einmal \n) sein.
  • Einige MIME-Typen geben mehr als eine Erweiterung zurück. Sie können cut -d ' ' -f 1höchstens eine Erweiterung abrufen, es muss aber nicht die gewünschte sein.
  • Daher kann eine benutzerdefinierte Map-Datei anstelle von /etc/mime.typesnützlich sein. Dieser Befehl zeigt Ihnen, welche MIME-Typen im aktuellen Verzeichnis (und den Unterverzeichnissen) vorhanden sind:

    find . -type f -exec file -b --mime-type {} + | sort | uniq
    
  • grepsollte nicht mehr als einmal übereinstimmen (zumindest mit /etc/mime.types); ^(Zeilenanfang) und $'\t'(Tabulator) sind da, um teilweise Übereinstimmungen zu vermeiden. Verwenden Sie grep -m 1 ...(oder head -n 1später), um sicherzugehen, dass Sie höchstens eine Zeile erhalten.

Antwort2

Erwähnenswert, denke ich, es zeigt die Erweiterung für ein paar Dateitypen

file --preserve-date --special-files --extension *

Ergebnis:

BMP_file:          ???
CPP_file:          ???
FIFO_file:         ERROR: (null)
GZ_file:           ???
HAR_file:          ???
H_file:            ???
HTML_file:         ???
JAR_file:          zip/cbz
JAVA_CLASS_file:   ???
JAVA_JAVA_file:    ???
JPG_file:          jpeg/jpg/jpe/jfif
MKV_file:          ???
MP3_file:          ???
MP4_file:          ???
ODT_file:          ???
PDF_file:          ???
PNG_file:          ???
PPS_file:          ???
SHELL_SCRIPT_file: ???
SO_file:           ???
TIFF_file:         ???
TMP_file_GBQcW:    ???
XML_file:          ???
ZIP_file:          zip/cbz

verwandte Informationen