Wie füge ich eine Dateierweiterung hinzu?

7

Mein Fotoimporter hat Dateien von meiner Kamera verschoben und umbenannt, aber ich habe vergessen anzugeben, dass die Dateierweiterung beibehalten werden soll. So habe ich mehrere Ordner mit Hunderten von JPG und AVI - Dateien , die alle fehlen ihre richtige Erweiterung.

Es gibt nicht so viele Videodateien, so dass ich sie entweder vor oder nach einer allgemeinen Massenumbenennung in JPG manuell umbenennen kann.

Um die Sache noch komplizierter zu machen, enthalten die Dateinamen Leerzeichen, daher kann ich das nicht, mv "*" "*.jpg"weil das nicht funktioniert (aber genau das würde ich unter DOS / Windows tun).

Ich weiß, dass Linux voller mächtiger Befehle ist. Wie kann ich Dateien massenweise umbenennen, um eine JPG-Erweiterung hinzuzufügen, wenn diese Dateien Leerzeichen enthalten?

Bitte sagen Sie nicht "Verwenden Sie keine Leerzeichen", da ich wirklich nicht danach frage. Vielen Dank.

Torben Gundtofte-Bruun
quelle
Okay, ich werde Ihnen nicht sagen, dass Sie Leerzeichen verwenden sollen, aber wenn Sie es sich später anders überlegen, versuchen Sie find /PATH/TO/FOLDER -depth -name "* *" -execdir rename 's/ /_/g' "{}" \; (Quelle), wodurch alle Leerzeichen in Dateien und Ordnern und Unterordnern für Sie ersetzt werden.
Tom Brossman

Antworten:

16

Shell Globs sollten auch mit Leerzeichen in den Namen funktionieren, wenn sie richtig verwendet werden, z

rename -nv -- 's/$/.jpg/' *

oder

for file in *; do echo mv -- "$file" "$file.jpg"; done

[HINWEIS: Dies sind keine Operationen, bis der nSchalter oder die echoentfernt werden. Sie können also vor dem Festschreiben den korrekten Austausch überprüfen.]

Wenn Sie automatisch zwischen JPG- und AVI-Dateien unterscheiden möchten, ist dies auch mit einer komplexeren Schleife und dem Befehl fileoder möglichmimetype

Steeldriver
quelle
+1 aber beachte, dass 1) dies auch Verzeichnisse umbenennt und 2) es nicht wiederkehrt, was ich denke, dass das OP benötigt, da sie "mehrere Verzeichnisse" haben.
Terdon
Rekursion ist nicht wichtig, aber eine gute Beobachtung. Ich mag die Art und Weise, wie Sie dies als Demo-dann-True-Modell gebaut haben.
Torben Gundtofte-Bruun
Vielen Dank, aber Sie sollten die Antwort von @ terdon als allgemeinere (und robustere) Lösung betrachten.
Steeldriver
@steeldriver Sie sollten wahrscheinlich angeben, welche renameSie verwenden. Dies ist diejenige, die mit Perl kommt , nicht die üblichere und weniger nützliche, die mit util-linux kommt
@BroSlow fairer Punkt, aber der Ubuntu (und Debian) Standard renameist der Perl. Der von util-linuxist /usr/bin/rename.ulunter Ubuntu, während er /usr/bin/renamestandardmäßig ein Symlink zu ist/usr/bin/prename . Im Allgemeinen ist es in der Debian-Welt (und dies ist Ask Ubuntu ) sicher anzunehmen, prenamesofern nicht anders angegeben.
Terdon
7

Wenn Sie eine komplexere Hierarchie haben, benötigen Sie einen etwas ausgefeilteren Ansatz. Sie können entweder die globstarOption von bash verwenden, mit der **null oder mehr Verzeichnisse und Unterverzeichnisse abgeglichen werden können, oder Sie können verwenden find.

  1. Globstar

    shopt -s globstar
    for f in **/*; do [ -f "$f" ] && mv "$f" "$f".jpg; done
    

    Die [ -f "$f" ] &sorgt dafür , dass der mvBefehl nur auf Dateien und Verzeichnisse nicht ausgeführt wird.

  2. find

    find . -type f -print0 | xargs -0 -I{} mv "{}" "{}".jpg
    

    Die -type fgarantiert , dass wir nur Dateien und keine Verzeichnisse und die finden print0Ursachen findseiner Ausgabe drucken getrennt mit dem Null - Zeichen ( \0) anstelle von Zeilenumbrüchen. Dies stellt sicher, dass wir korrekt mit Dateinamen umgehen, die Leerzeichen, Zeilenumbrüche oder andere Verrücktheiten enthalten.

    xargsNimmt eine Liste der Eingaben und führt den darauf angegebenen Befehl aus. Das -0Flag weist es an, eine durch Null getrennte Eingabe zu erwarten, und das -I{}ersetzt jede Instanz von {}durch jeden der übergebenen Eingabedatensätze (in diesem Fall Dateien).

Terdon
quelle
Vielen Dank, dass Sie "The Linux Way" gezeigt haben. Diese Suchmethode erweist sich als recht flexibel.
Ray Foss
Um die Erweiterung ohne Anhängen mit einer ähnlichen Technik groß zu schreiben, wird davon ausgegangen, dass keine Dateien mit einem% benannt sind:find -name *.jpg -print0 | xargs -0 -I{} sh -c "printf \"'{}' \" && printf \"'{}\" | head -c-4 && printf \".JPG'\0\"" | xargs -0 -I{} sh -c "mv {}"
Ray Foss
4

Ich würde Ihnen raten, ein Programm namens zu verwenden pyrenamer .

Öffnen Sie es und geben Sie im Muster Umbenannter Dateiname ein {1}.jpg.

Tim
quelle
Sehr einfach und arbeitete wie Charme
Kendor
4

Bitte lesen Sie, man renamebevor Sie dies versuchen

Dies sollte wie ein Zauber wirken.

In einem Terminal:

cd /path/to/exported/imgs/folder/
rename  's/(\w+)$/$1\.jpg/' *

Bitte ändern Sie "jpg" auf das, was Sie brauchen.

rename kann Perl-Ausdrücke verwenden .. Ihr bester Freund

In der ersten Zeile haben Sie Ihr Dateiverzeichnis eingegeben

cd /path/to/exported/imgs/folder/

Der svorige Ausdruck zeigt eine Substitution an

benenne ' s / (\ w +) $ / $ 1 \ .jpg / ' * um

Anschließend wird nach einer Datei mit einem alphanumerischen Namen und einem Unterstrich gesucht, jedoch ohne Erweiterung

benenne 's / (\ w +) $ /$1\.jpg/' * um

Und ersetzen Sie es. ein Punkt jpg

benenne 's / (\ w +) $ / $ 1 \ .jpg /' * um

Schließlich auf jede Datei im Ordner der ersten Zeile anwenden

benenne 's / (\ w +) $ / $ 1 \ .jpg /' * um
Quijote Shin
quelle
2

Diese Situation tritt bei der Verwaltung von Systemen häufig auf, insbesondere beim Umgang mit Dateinamen, die von Windows-Anwendungen erstellt wurden. .jpgBerücksichtigen Sie diese Befehlsliste, um Erweiterungen für Dateinamen ohne Erweiterung hinzuzufügen .

find ./example -type f -name '*' -print0 | xargs -0 -I'{}' mv '{}' '{}'.jpg

find's -print0generiert NULL-Zeichen für Trennzeichen, xargs's -0akzeptiert diese NULL-Trennzeichen. Dies gilt auch für alle Unterverzeichnisse. Ersetzen Sie daher unbedingt den Pfad './example'.

renameist ein großartiger Befehl, aber sowohl in der Implementierung als auch in der Spezifikation distro-spezifisch. Ich benutze renamenormalerweise Dinge wie in der Kommandozeile, aber ich schreibe immer in GNU-Utils-Standards für meine Skripte.

JM Becker
quelle