Wie kann ich die Erweiterung (en) einer Datei basierend auf ihrem Inhalt erhalten?

452
confetti

Ich habe vor, eine Reihe von Bildern von einer Website herunterzuladen, die nicht mit einer Erweiterung versehen ist. Ich möchte also eines hinzufügen, das auf dem Inhalt der Datei oder dem Mime-Typ basiert.

file <filename> macht einen tollen Job bei der Identifizierung des Dateityps, aber ich brauche die Erweiterung.

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

Dies ist aus fileder Manpage, aber es scheint 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 an sie weitergebe, auch für diejenigen, die bereits eine geeignete Erweiterung haben. All dies sind gültige Dateien ihrer Art und perfekt durch anerkannt bekommen fileohne --extension.

Warum funktioniert das file --extensionnicht für mich und was kann ich verwenden, um die Dateierweiterung zu erhalten?

Eine Idee wäre file --mime-type, ein Dispatch-Tabellen-Array zu verwenden und dann zu erstellen, das bekannte Mime-Typen auf ihre Erweiterungen abbildet, aber ich hätte lieber eine einfachere und sicherere Lösung.

0
Ich gehe davon aus, dass Sie versucht haben, die Erweiterung aus dem Dateinamen zu entfernen und dann `file` dagegen ausgeführt? Appleoddity vor 6 Jahren 0
Ja. Die Ausgabe ist für jede Datei gleich "???". confetti vor 6 Jahren 0
Was ist Ihre Dateiversion? Dateiversion cybernard vor 6 Jahren 0
@cybernard `file-5.33` confetti vor 6 Jahren 0

1 Antwort auf die Frage

1
Kamil Maciorowski

Warum klappt das file --extensionnicht bei mir?

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

Vielleicht nur ein sehr, sehr unvollständiges Feature?

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

Eine Idee wäre file --mime-type, ein Dispatch-Tabellen-Array zu verwenden und dann zu erstellen, das bekannte Mime-Typen auf ihre Erweiterungen abbildet, aber ich hätte lieber eine einfachere und sicherere Lösung.

Beachten Sie, dass eine solche Karte existiert /etc/mime.types. Sehen Sie sich eine weitere Frage zu Unix & Linux SE an . Basierend auf einer der Antworten kam ich zu folgender Funktion:

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

Verwendungszweck:

getext test_text_file.txt # it takes just one argument 

Passen Sie es an Ihre Bedürfnisse an, machen Sie es zu einem Skript usw. Das Hauptanliegen ist:

  • Bei Erfolg (Beendigungsstatus 0) ist die Ausgabe möglicherweise nicht leer oder leer (nicht gerade \n).
  • Einige MIME-Typen geben mehrere Erweiterungen zurück. Sie können cut -d ' ' -f 1höchstens eine davon erhalten, es ist jedoch möglicherweise nicht die, die Sie möchten.
  • Daher kann eine benutzerdefinierte Kartendatei 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 passen (zumindest mit /etc/mime.types); ^(Zeilenanfang) und $'\t'(Tab) dienen dazu, partielle Übereinstimmung zu vermeiden. Verwenden Sie grep -m 1 ...(oder head -n 1später), um sicherzustellen, dass Sie höchstens eine Zeile erhalten.

Vielen Dank für diese großartige Antwort und den Hinweis auf `/ etc / mime.types`. Dies funktioniert perfekt für mich. confetti vor 6 Jahren 0