Fügen Sie rekursiv allen Dateien eine Dateierweiterung hinzu

106

Ich habe einige Verzeichnisse und Unterverzeichnisse, die Dateien ohne Dateierweiterung enthalten. Ich möchte zu .jpgallen in diesen Verzeichnissen enthaltenen Dateien hinzufügen . Ich habe Bash-Skripte zum Ändern der Dateierweiterung gesehen, aber nicht nur zum Hinzufügen eines. Es muss auch rekursiv sein, kann jemand bitte helfen?

Robjmills
quelle

Antworten:

228

Alternativer Befehl ohne explizite Schleife ( man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Erläuterung: Dadurch werden rekursiv alle Dateien ( -type f) ab dem aktuellen Verzeichnis ( .) gefunden und der Befehl move ( mv) auf jede dieser Dateien angewendet. Beachten Sie auch die Anführungszeichen {}, damit Dateinamen mit Leerzeichen (und sogar Zeilenumbrüchen ...) ordnungsgemäß behandelt werden.

Stephan202
quelle
7
Dies funktioniert insbesondere dann besser, wenn die Verzeichnisstruktur eine große Anzahl von Dateien enthält (was dazu führt, dass sich Bash über die Länge der Liste der zu iterierenden Dateien aufregt).
DrAl
@Al, wenn Sie sich auf eine forSchleife beziehen, die die Bash stört, um eine Liste von Dateien zu durchlaufen, ist dies nicht korrekt. Die Bash- forSchleife gibt iterativ jeden mvBefehl aus.
Nik
Frage: Richtet findzuerst eine Liste von Dateien ein, bevor die -execAnweisung ausgeführt wird? Ich denke schon, aber ich möchte diesen Punkt klarstellen, bevor ich Endlosschleifen codiere.
Boldewyn
2
Dieser Befehl findet auch Dateien mit der Erweiterung. Ist es das, was OP will?
Ghostdog74
1
@ Ghostdog74: Da er diese Antwort akzeptiert hat, hat das oben Genannte anscheinend den Trick getan. Andernfalls reicht das Hinzufügen aus, wie Sie unten erwähnt -not -name "*.*"haben.
Stephan202
62

Dadurch werden Dateien ohne Erweiterung gefunden und Ihre JPG-Datei hinzugefügt

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;
Ghostdog74
quelle
Dies wird in 99% der Fälle definitiv das gewünschte Ergebnis liefern. +1
Les
9

Dies ist etwas spät, aber ich dachte, ich würde hinzufügen, dass eine bessere Lösung (obwohl vielleicht weniger lesbar) als die bisherigen sein könnte:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

Verwendung der find | xargs Musters führt im Allgemeinen zu einer effizienteren Ausführung, da Sie nicht für jede Datei einen neuen Prozess erstellen müssen.

Beachten Sie, dass hierfür die Version der Umbenennung erforderlich ist, die in Distributionen mit Debian-Geschmack (auch als Vorname bezeichnet) enthalten ist, und nicht die herkömmliche Umbenennung. Es ist jedoch nur ein winziges Perl-Skript, sodass es einfach genug wäre, den obigen Befehl auf jedem System zu verwenden.

Chad Huneycutt
quelle
4

so was,

for f in $(find . -type f); do mv $f ${f}.jpg; done

Ich erwarte nicht, dass Sie durch Leerzeichen getrennte Dateinamen haben.
Wenn Sie dies tun, müssen die Namen ein wenig verarbeitet werden.

Wenn Sie den Befehl aus einem anderen Verzeichnis ausführen möchten,
können Sie die ersetzen find .mit find /target/directory.

nik
quelle
1
Hier fehlt ein 'do' und wenn der Dateiname Leerzeichen enthält, ist es möglicherweise besser, den Dateinamen in Anführungszeichen zu setzen: für f in $ (find. -Typ f); mache mv "$ f" "$ {f} .jpg"; fertig
DrAl
und vermutlich würde ich das aus dem obersten Verzeichnis ausführen?
Robjmills
@seengee: ja. Beachten Sie, dass bei diesem Befehl auch der Bindestrich fehlt -type.
Stephan202
Ich musste irgendwohin gehen und zu schnell tippen ... jetzt reparieren.
Nik
1

Um alle Dateien ohne Erweiterung in Windows Basic umzubenennen, können Sie Folgendes tun: ren * *.jpg Da die Datei keine Erweiterung hat, verwenden Sie einfach das *, oder wenn Sie PNG in JPG ändern möchten, verwenden Sieren *.png *.jpg

Nuno
quelle
0

rename

Ich bin mir nicht sicher, ob es Dateien ohne Erweiterungen umbenennen kann (ich bin gerade unter Windows 7).

dfa
quelle
1
es kann, aber es wird auch Verzeichnisse umbenennen, und es gibt keine Möglichkeit, es anzuweisen, rekursiv in Unterverzeichnissen zu arbeiten (zumindest mit der Version, die ich unter Ubuntu habe).
Mirod
Ich kenne mindestens zwei verschiedene Befehle rename, einen als C-Programm, das in util-linux-ng enthalten ist, und einen als Perl-Programm (von Wall selbst) auf den Debian-Maschinen unserer Universität. Eigentlich rekursiert keiner von beiden.
Boldewyn