it-swarm.com.de

Korrigieren Sie die Dateierweiterungen

Ich habe ungefähr 12000 Bilder von verschiedenen Dateitypen, aber jeder von ihnen wurde in * .jpg umbenannt.

Jetzt möchte ich ihnen ihre richtigen Erweiterungen zurückgeben, wie kann ich das tun?

15
akabhirav

Mit bash geht das relativ einfach:

for f in *jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+') 
    mv "$f" "${f%%.*}.${type,,}"  
done

Dies ist die gleiche Idee wie die Antwort von @ A.B, verwendet jedoch Shell-Globs anstelle von find. Der ${f%%.*} ist der Dateiname ohne Erweiterung. Mit dem Befehl -0 des Befehls file wird nach dem Dateinamen ein \0 ausgegeben, mit dem wir dann den Dateityp grep angeben. Dies sollte mit beliebigen Dateinamen funktionieren, einschließlich solcher, die Leerzeichen, Zeilenumbrüche oder anderes enthalten. Der ${type,,} ist ein Trick, um Erweiterungen in Kleinbuchstaben zu erhalten. Es würde PNG in png konvertieren.

Sie haben es in Ihrer Frage nicht gesagt, aber wenn Sie möchten, dass dies rekursiv ist und in Unterverzeichnisse verschoben wird, können Sie stattdessen Folgendes verwenden:

shopt -s globstar
for f in **/*jpg; do 
    type=$(file -0 -F" " "$f" | grep -aPo '\0\s*\K\S+') 
    mv "$f" "${f%%.*}.${type,,}"  
done

Der shopt -s globstar aktiviert die Globstar-Option von bash, mit der ** Unterverzeichnisse abgleichen kann:

globstar

Wenn festgelegt, stimmt das in einem Pfadnamen-Erweiterungskontext verwendete Muster ** mit allen Dateien und null oder mehr Verzeichnissen und Unterverzeichnissen überein. Wenn dem Muster ein/folgt, stimmen nur Verzeichnisse und Unterverzeichnisse überein.

22
terdon

Das folgende Skript kann verwendet werden, um eine falsch festgelegte Erweiterung (rekursiv) .jpg in die richtige Erweiterung umzubenennen. Falls eine nicht lesbare Datei gefunden wird, wird dies in der Ausgabe des Skripts gemeldet.

Das Skript verwenden, um die imghdr Modul, die folgenden Arten zu erkennen: rgb, gif, pbm, pgm, ppm, tiff, rast, xbm, jpeg, bmp, png. Mehr zum Modul imghdrhier . Die Liste kann, wie im Link erwähnt, um weitere Typen erweitert werden.

Wie in der Frage erwähnt, werden Dateien mit der Erweiterung .jpg speziell umbenannt. Mit einer geringfügigen Änderung kann eine Erweiterung oder ein bestimmter Satz von Erweiterungen in die richtige Erweiterung umbenannt werden (oder ohne Erweiterung, z. B. hier ).

Das Drehbuch:

#!/usr/bin/env python3
import os
import imghdr
import shutil
import sys

directory = sys.argv[1]

for root, dirs, files in os.walk(directory):
    for name in files:
        file = root+"/"+name
        # find files with the (incorrect) extension to rename
        if name.endswith(".jpg"):
            # find the correct extension
            ftype = imghdr.what(file)
            # rename the file
            if ftype != None:
                shutil.move(file, file.replace("jpg",ftype))
            # in case it can't be determined, mention it in the output
            else:
                print("could not determine: "+file)

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es als rename.py
  2. Führen Sie es mit dem Befehl:

    python3 /path/to/rename.py <directory>
    
11
Jacob Vlijm

Hinweis: Mein Ansatz scheint zu komplex zu sein. Ich würde es vorziehen, wenn Terdons an Ihrer Stelle antworten.


Mit dem Befehl file können Sie den Dateityp bestimmen:

% file 20050101_14-24-37_330.jpg 
20050101_14-24-37_330.jpg: JPEG image data, EXIF standard 2.2, baseline, precision 8, 1200x1600, frames 3

% file test.jpg
test.jpg: PNG image data, 1192 x 774, 8-bit/color RGBA, non-interlaced

Mit diesen Informationen können die Dateien umbenannt werden:

Bitte führen Sie einen Test durch, bevor Sie den Befehl auf Ihre Bilder anwenden

find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} | 
 awk -F " image data" '{print $1}' | 
  awk -F"<separator> " '{
   system("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)
   }'

Beispiel

% find . -type f -name "*.jpg"
./test.jpg
./sub/20050101_14-24-37_330.jpg

% find . -type f -iname "*.jpg" -print0 | xargs -0 -I{} file -F"<separator>" {} | awk -F " image data" '{print $1}' | awk -F"<separator> " '{system ("mv \""$1"\" $(dirname \""$1"\")/$(basename -s .jpg \"" $1 "\")."$2)}'

% find . -type f -iname "*"    
./test.PNG
./sub/20050101_14-24-37_330.JPEG
3
A.B.