Ich möchte die Dateien in einem Verzeichnis in fortlaufende Nummern umbenennen. Basierend auf dem Erstellungsdatum der Dateien.
Beispiel sadf.jpg
bis 0001.jpg
, wrjr3.jpg
bis 0002.jpg
usw. die Anzahl der führenden Nullen in Abhängigkeit von der Gesamtanzahl der Dateien (keine zusätzlichen Nullen erforderlich, wenn nicht erforderlich).
Versuchen Sie, eine Schleife, let
und printf
für die Auffüllung zu verwenden:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
die Verwendung des Flags -i
verhindert, dass vorhandene Dateien automatisch überschrieben werden.
Schönheit in einer Linie
ls -v | cat -n | while read n f; do mv "$f" "$n.ext"; done
Ändern Sie .ext mit dem gewünschten .png, .jpg oder einem anderen.
Ich mag die Lösung von gauteh wegen ihrer Einfachheit, aber sie hat einen wichtigen Nachteil. Wenn Sie mit Tausenden von Dateien arbeiten, können Sie die Meldung "Argumentliste zu lang" ( mehr dazu ) erhalten. Zweitens kann das Skript sehr langsam werden. In meinem Fall wurde das Skript auf ca. 36.000 Dateien ausgeführt, das Skript wurde um ca. ein Artikel pro Sekunde! Ich weiß nicht genau, warum das passiert, aber die Regel, die ich von Kollegen bekam, war "find
ist dein Freund".
find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
Um Elemente und Build-Befehle zu zählen, wurde gawk verwendet. Beachten Sie jedoch den Hauptunterschied. Standardmäßig sucht find
nach Dateien im aktuellen Verzeichnis und dessen Unterverzeichnissen. Beschränken Sie die Suche daher ggf. nur auf das aktuelle Verzeichnis (verwenden Sie man find
, um zu erfahren, wie).
die Verwendung der Pero-Lösung unter OSX erforderte einige Änderungen. Ich benutzte:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
Hinweis: Die Backslashes sind für die Zeilenfortsetzung vorhanden
edit 20. Juli 2015: eingebautes @ klaustopher-Feedback, um das \"%s\"
-Argument des mv
-Befehls zu zitieren, um Dateinamen mit Leerzeichen zu unterstützen.
mit dem Befehl "Umbenennen"
rename -N 0001 -X 's/.*/$N/' *.jpg
oder
rename -N 0001 's/.*/$N.jpg/' *.jpg
Ein sehr einfacher Bash-One-Liner, der die ursprünglichen Erweiterungen beibehält, führende Nullen hinzufügt und auch in OSX funktioniert:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
Vereinfachte Version von http://ubuntuforums.org/showthread.php?t=1355021
Um in allen Situationen zu arbeiten, setzen Sie ein\"für Dateien, die im Namen Platz haben
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
Wenn Ihre rename
-N
nicht unterstützt, können Sie Folgendes tun:
ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
Edit Um mit einer bestimmten Nummer zu beginnen, können Sie den (etwas hässlich aussehenden) Code verwenden. Ersetzen Sie einfach 123 durch die gewünschte Nummer:
ls -1 -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'
Dies listet die Dateien nach der Erstellungszeit auf (neueste zuerst, fügen Sie -r
zu ls hinzu, um die Sortierung umzukehren), und sendet dann diese Liste der Dateien, die umbenannt werden sollen. Umbenennen verwendet Perl-Code im Regex zum Formatieren und Inkrementieren des Zählers.
Wenn Sie jedoch JPEG-Bilder mit EXIF-Informationen verwenden, würde ich exiftool
empfehlen.
Dies ist aus der exiftool-Dokumentation unter "Umbenennen von Beispielen".
exiftool '-FileName<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%e dir
Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading '-' if the file already exists ("%-c"), and
preserving the original file extension (%e). Note the extra '%' necessary to escape the filename codes (%c and %e) in the date format string.
Installieren Sie unter OSX das Umbenennungsskript von Homebrew:
brew install rename
Dann kannst du es ganz einfach lächerlich machen:
rename -e 's/.*/$N.jpg/' *.jpg
Oder um ein Nizza-Präfix hinzuzufügen:
rename -e 's/.*/photo-$N.jpg/' *.jpg
Sie können auch ls verwenden.
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash
Auch hier wird Peros Lösung mit wenigen Änderungen verwendet, da find
die Verzeichnisstruktur durchläuft, in der die Elemente in den Verzeichniseinträgen gespeichert sind. Dies ist (meistens) konsistent von Run zu Run auf derselben Maschine und wird im Wesentlichen "Reihenfolge der Datei-/Verzeichniserstellung" sein, wenn keine Löschungen vorgenommen wurden.
In einigen Fällen müssen Sie jedoch eine logische Reihenfolge erhalten, beispielsweise nach dem Namen, der in diesem Beispiel verwendet wird.
find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
Nehmen wir an, wir haben diese Dateien in einem Verzeichnis, aufgelistet in der Reihenfolge der Erstellung, wobei die erste die älteste ist:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
dann gibt ls -1cr
genau die obige Liste aus. Sie können dann rename
verwenden:
ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d$1", $i++)/e'
welche Ausgänge
rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
Die Warnung "Verwendung eines nicht initialisierten Werts […]" wird für Dateien ohne Erweiterung angezeigt. Sie können es ignorieren.
Entfernen Sie -n
aus dem Befehl rename
, um die Umbenennung tatsächlich anzuwenden.
Diese Antwort ist inspiriert von Lukas Antwort vom April 2014 . Es ignoriert Gnuts Anforderung, die Anzahl der führenden Nullen abhängig von der Gesamtanzahl der Dateien festzulegen.
Ich hatte ein ähnliches Problem und schrieb aus diesem Grund ein Shell-Skript. Ich habe mich entschieden, es zu posten, obwohl viele gute Antworten bereits veröffentlicht wurden, weil ich denke, dass es für jemanden hilfreich sein kann. Fühlen Sie sich frei, um es zu verbessern!
@Gnutt Das gewünschte Verhalten kann durch folgende Eingabe erreicht werden:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
Wenn die Option -r
weggelassen wird, wird das Aufreiben nur simuliert (sollte für das Testen hilfreich sein).
Die Option L beschreibt die Länge der Zielnummer (die mit führenden Nullen gefüllt wird) Es ist auch möglich, ein Präfix/Suffix mit den Optionen -p <prefix>
-s <suffix>
hinzuzufügen.
Falls jemand möchte, dass die Dateien vor der Nummerierung numerisch sortiert werden, entfernen Sie einfach die Option -o modtime
.
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
Umbenennen in -vn - remove n für den Testmodus aus
{$ i = 1;} - Kontrollstartnummer
"% 04d.jpg" - Steuerung Zählwert Null 04 und Ausgangserweiterung einstellen .jpg
Folgen Sie dem Befehl, umbenennen Sie alle Dateien in Sequenz und auch Kleinbuchstabenerweiterung:
rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *
Dieser Oneliner listet alle Dateien im aktuellen Verzeichnis auf, sortiert nach Erstellungszeitstempel in umgekehrter Reihenfolge (dh die älteste Datei befindet sich am Anfang) und benennt sich automatisch mit nachgestellten Nullen um, je nach Anzahl der Dateien. Die Dateierweiterung bleibt erhalten.
Ich habe seit Jahren nur einen Ordner für Handybilder und -filme. Wenn Sie diesen Befehl anwenden, sind meine Bilder und Filme bereit für eine Diaschau in der richtigen Reihenfolge auf dem Fernseher oder für die Archivierung.
Beachten Sie, dass bei Dateinamenskollisionen Dateien verloren gehen. Umbenennen Sie also zunächst in etwas Ungewöhnliches wie temp001.jpg
und führen Sie dann den endgültigen Dateinamen aus.
DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done
a=1
for i in *.jpg; do
mv -- "$i" "$a.jpg"
a=`expr $a + 1`
done
Sortiert nach Zeit, begrenzt auf jpg, führende Nullen und einen Basisnamen (falls Sie wahrscheinlich einen möchten):
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(alles in einer Zeile, ohne den \
)
Die meisten anderen Lösungen überschreiben vorhandene Dateien, die bereits als Nummer bezeichnet wurden. Dies ist insbesondere ein Problem, wenn Sie das Skript ausführen, weitere Dateien hinzufügen und dann das Skript erneut ausführen.
Dieses Skript benennt zunächst vorhandene numerische Dateien um:
#!/usr/bin/Perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can't opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ /\A\.\.?\z/;
my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
Wenn Sie den Bildanmerator zum Beschriften der Bilder verwenden.
$ make qt5py3
$ python3 labelImg.py
Für mich hat diese Kombination von Antworten perfekt funktioniert:
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
ls -v
hilft bei der Bestellung von 1 10 9 in der richtigen Reihenfolge: 1 9 10 Reihenfolge, wodurch Dateinamenserweiterungsprobleme mit jpg JPG jpeg vermieden werdengawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }'
wird mit 4 Zeichen und führenden Nullen neu nummeriert. Durch das Vermeiden von mv versuche ich nicht versehentlich, etwas zu überschreiben, das bereits vorhanden ist, indem ich versehentlich dieselbe Nummer habe.bash
wird ausgeführtSeien Sie sich bewusst, was @xhienne gesagt hat: Das Weiterleiten unbekannter Inhalte an bash ist ein Sicherheitsrisiko. Dies war jedoch bei mir nicht der Fall, da ich meine gescannten Fotos verwendete.