Batch: Bilder sortieren

schl3ck

schon lange hier
Hallo,

ich wollte mal meine Bilder in einem Ordner sortieren (mit Zahlen natürlich), wobei ich immer wieder mal ein Bild warum auch immer lösche, oder neue kommen hinzu.
Um diesem Problem her zu werden, wollte ich, dass ein Batch-Skript den ganzen Kram erledigt.

Irgendwie habe ich auch schon etwas zusammen gestellt, nur bricht es immer bei der for-Schleife ab :( (Fehlermeldung im angehängten Bild; mit "Druck-Taste" aufgenommen, da das Fenster sofort verschwindet)

Mein Ergebnis bis jetzt:
Code:
::@echo off
set i=0001
set D=E:\Neuer Ordner
pause
for /f %%a in ('dir "%D%\*" /A:-D /B') do (
    set A=%%~a
    set B=!A:~4,3!            :: soll die 4.-7. Zeichen im Dateinamen extrahieren
    if not %B%==%i% ( 
        set bild=IMG_%i%.jpg
        ren %A% %bild%        :: Umbenennen
    )
    set /a i=%i%+1                                 :: Rechenvorgang (1 zur Zahl hinzufügen)
    if /i %i% LSS 10 ( set i=000%i% ) else ( 
    if /i %i% LSS 100 ( set i=00%i% ) else ( 
    if /i %i% LSS 1000 set i=0%i% ))               :: durch den Rechenvorgang wurden die 000 am Anfang entfernt -> wieder hinzufügen
)
pause

Das ganze soll die Bilder im Schema "IMG_xxxx.jpg" benennen. Wenn jetzt zB die Datei IMG_0001.jpg fehlt, aber die 0002 vorhanden ist, soll er die 0002 in 0001 umbenennen.
Was da jetzt genau in der for-Schleife steht, weiß ich ehrlich gesagt nicht. hab das nur aus dem Thema "Ersten 4 Zeichen von Dateinamen in .txt schreiben" (oder so ähnlich).

Ich hoffe, mir kann jemand helfen
 

Anhänge

  • batch-sortieren.jpg
    batch-sortieren.jpg
    107 KB · Aufrufe: 228
Danke, jetzt führt er es zwar aus, aber nach dem Ende jeder Schleife steht "Syntaxfehler" und keine einzige Datei wurde umbenannt.

Code:
::@echo off
set i=0001
set D=E:\Neuer Ordner
pause
for /f %%a in ('dir "%D%\*.jpg" /A:-D /B') do (             :: .jpg hinzugefügt
    set A=%%~a
    set B=!A:~4,3!            :: soll die 4.-7. Zeichen im Dateinamen extrahieren
    if not "%B%"=="%i%" (           :: "" hinzugefügt
        set bild=IMG_%i%.jpg
        ren "%A%" "%bild%"        :: Umbenennen
    )
    set /a i=%i%+1                                 :: Rechenvorgang (1 zur Zahl hinzufügen)
    if /i %i% LSS 10 ( set i=000%i% ) else ( 
    if /i %i% LSS 100 ( set i=00%i% ) else ( 
    if /i %i% LSS 1000 set i=0%i% ))               :: durch den Rechenvorgang wurden die 000 am Anfang entfernt -> wieder hinzufügen
)
pause

Ein weiteres Problem ist, dass er direkt nach dem deklarieren, noch immer die alte Zahl in der Variable drinnen hat (wahrscheinlich deswegen der Syntaxfehler)
 
Frage am Rande:
Muss es eine Batch sein weil Du lernen willst, wie man das per Batch macht oder kommt es Dir nur auf das Ergebnis an?

Müssen die Bilder genau diese Art der Nummerierung haben, oder dürfen sie auch IMG(1).jpg IMG(2).jpg usw. heißen?
Wenn letzteres:
Der Standard Windows Explorer ist dein Freund: Einfach alle Bilder mit Strg+A markieren, dann Rechtsklick auf die erste Datei und Umbenennen auswählen (alternativ geht auch die Taste F2), IMG(1).jpg eingeben und die Eingabetaste drücken. Alle weiteren Dateien werden dann ebenfalls umbenannt und die Nummer in Klammern wird immer einen hochgezählt.

ansonsten:
XNView beinhaltet ein leistungsfähiges Massen-Umbenennungstool, in dem man das und noch ein wenig mehr machen kann - und ich glaube die anderen Bildbetrachter können so etwas auch...


edit:
Hab auch noch was gescribbelt:
Code:
@echo off
setlocal enabledelayedexpansion
set /a count=0
for /f "tokens=*" %%a in ('dir /b /od *.jpg') do (
 echo ren %%a IMG_!count!.jpg
 set /a count+=1
)

Wenn das klappt, so Wie Du Dir das vorgestellt hast, kannst Du das echo vor ren entfernen und dann werden die Dateien tatsächlich umbenannt und nicht nur die neuen Namen ausgegeben.
Anstelle des /od Parameters kannst Du natürlich auch andere Lesesortierungen angeben, siehe dir /?
Des weiteren siehe set /? und for /? und setlocal /? für Infos was Du noch so alles damit anrichten kannst und warum da enabledelayedexpansion gesetzt ist.

Wenn Du allerdings noch Vornullen dabei haben willst, musst Du selbst ausklamüsern, wie das geht, aber das hattest Du ja schon weiter oben gelöst :)
 
Zuletzt bearbeitet:
Danke, jetzt funtzt es :D

Als erstes ging es mir nur ums Ergebnis, aber wie du es jetzt erwähnt hast, lerne ich daraus natürlich auch. Ich hatte mir vorhin auch die interne Hilfe von der cmd.exe öfters durchgelesen, nur ist das für mich ein bisschen kompliziert geschrieben. Sonst wäre ich nie auf das Rechen mit set /a gekommen und das LSS hätt ich auch nicht gefunden ;)

Nochmal tausend Dank :)

P.S.: Mein vollständiger Code:
Code:
@echo off
setlocal enabledelayedexpansion
set count=0001
for /f "tokens=*" %%a in ('dir /b /od *.jpg') do (
	ren %%a IMG_!count!.jpg
	set /a count+=1
	if /i !count! LSS 10 ( set count=000!count! ) else ( 
	if /i !count! LSS 100 ( set count=00!count! ) else ( 
	if /i !count! LSS 1000 set count=0!count! ))
)
pause

Edit: Doch nicht, er schreibt immer Syntaxfehler hin :(
 
Zuletzt bearbeitet:
autsch - bin voll in den Oktalzahlfehler und einen Zweiten reingerauscht....

Code:
@echo off
setlocal enabledelayedexpansion
set /a count=1
for /f "tokens=*" %%a in ('dir /b /on *.jpg') do (
IF 1!count! LSS 1000 (
 SET count=1000!count!
) 
echo ren "%%a" "IMG_!count:~-4!.jpg"
set /a count += 1
)
pause
Probier dies mal, das sollte sauber laufen, hier waren es die fehlenden "", die den Syntaxfehler verursachten. echo vor ren entfernen, wenn der Test erfolgreich war ;)

ps: hab noch /od durch /on ausgetauscht - man darf sich ja auch mal vertun bei der Sortierung:D
 
Hm, irgendwie komisch, dass der immer nur bis 8 zählt und dann von vorn anfängt :stupid
Kann man das irgendwie ändern? Es scheint so, als wäre die Zahl falsch definiert.

Auch lässt er die Datei "IMG_0007.JPG" einfach aus :unsure:
 
Grunz! <- ersetzen durch einen belibigen Fluch der hier unter die Fluchzensur fallen würde.


Ja, ich weiß, woran es liegt, habe aber momentan keine Idee, wie ich das umgehen kann:
Windows interpretiert unter bestimmten Umständen 08 und andere Zahlen, die mit 0 anfangen, als Oktalzahl. Man müsste das ganze sauber in Strings umwandeln können.

VBS wäre eine Alternative - oder direkt die Powershelll mit .NET benutzen, denn das Zahlenproblem ist eins, wofür Batch Dateien im alten Stil eigentlich nicht geschaffen sind.
 
Vielleicht geht es ja mit
Code:
@echo off
setlocal enabledelayedexpansion
set /a count=1
for /f "tokens=*" %%a in ('dir /b /on *.jpg') do (
IF !count! LSS 10 (ren "%%a" "IMG_000!count!.jpg") else (
IF !count! LSS 100 ( ren "%%a" "IMG_00!count!.jpg"

usw. usw. ...
(nicht getestet, wild geraten)
 
Jetzt zählt er zwar richtig, lässt aber beim Finden Dateien aus (zB: IMG_0007.jpg, IMG_0030.jpg, IMG_0048.jpg, IMG_0069.jpg, IMG_0072.jpg)

Sieht zB so in der Console aus:
Code:
ren "IMG_0001.jpg" "IMG_0001.jpg"
ren "IMG_0002.JPG" "IMG_0002.jpg"
ren "IMG_0003.JPG" "IMG_0003.jpg"
ren "IMG_0004.JPG" "IMG_0004.jpg"
ren "IMG_0005.JPG" "IMG_0005.jpg"
ren "IMG_0006.JPG" "IMG_0006.jpg"     :: Hier fehlt was
ren "IMG_0008.JPG" "IMG_0007.jpg"
ren "IMG_0009.JPG" "IMG_0008.jpg"
ren "IMG_0010.JPG" "IMG_0009.jpg"
ren "IMG_0011.JPG" "IMG_0010.jpg"
ren "IMG_0012.JPG" "IMG_0011.jpg"
ren "IMG_0013.JPG" "IMG_0012.jpg"
ren "IMG_0014.JPG" "IMG_0013.jpg"
ren "IMG_0015.JPG" "IMG_0014.jpg"
ren "IMG_0016.JPG" "IMG_0015.jpg"
ren "IMG_0017.jpg" "IMG_0016.jpg"
ren "IMG_0018.jpg" "IMG_0017.jpg"
ren "IMG_0019.jpg" "IMG_0018.jpg"
ren "IMG_0020.jpg" "IMG_0019.jpg"
ren "IMG_0021.jpg" "IMG_0020.jpg"
ren "IMG_0022.jpg" "IMG_0021.jpg"
ren "IMG_0023.jpg" "IMG_0022.jpg"
ren "IMG_0024.JPG" "IMG_0023.jpg"
ren "IMG_0025.JPG" "IMG_0024.jpg"
ren "IMG_0026.JPG" "IMG_0025.jpg"
ren "IMG_0027.JPG" "IMG_0026.jpg"
ren "IMG_0028.JPG" "IMG_0027.jpg"
ren "IMG_0029.JPG" "IMG_0028.jpg"     :: Hier fehlt was
ren "IMG_0031.JPG" "IMG_0029.jpg"
ren "IMG_0032.JPG" "IMG_0030.jpg"
ren "IMG_0033.JPG" "IMG_0031.jpg"
ren "IMG_0034.JPG" "IMG_0032.jpg"
ren "IMG_0035.JPG" "IMG_0033.jpg"
ren "IMG_0036.JPG" "IMG_0034.jpg"
ren "IMG_0037.JPG" "IMG_0035.jpg"
ren "IMG_0038.JPG" "IMG_0036.jpg"
ren "IMG_0039.JPG" "IMG_0037.jpg"
ren "IMG_0040.JPG" "IMG_0038.jpg"
ren "IMG_0041.JPG" "IMG_0039.jpg"
ren "IMG_0042.JPG" "IMG_0040.jpg"
ren "IMG_0043.JPG" "IMG_0041.jpg"
ren "IMG_0044.JPG" "IMG_0042.jpg"
ren "IMG_0045.JPG" "IMG_0043.jpg"
ren "IMG_0046.JPG" "IMG_0044.jpg"
ren "IMG_0047.JPG" "IMG_0045.jpg"     :: Hier fehlt was
ren "IMG_0049.JPG" "IMG_0046.jpg"
ren "IMG_0050.JPG" "IMG_0047.jpg"
ren "IMG_0051.JPG" "IMG_0048.jpg"
ren "IMG_0052.JPG" "IMG_0049.jpg"
ren "IMG_0053.JPG" "IMG_0050.jpg"
ren "IMG_0054.JPG" "IMG_0051.jpg"
ren "IMG_0055.JPG" "IMG_0052.jpg"
ren "IMG_0056.JPG" "IMG_0053.jpg"
ren "IMG_0057.JPG" "IMG_0054.jpg"
ren "IMG_0058.JPG" "IMG_0055.jpg"
ren "IMG_0059.JPG" "IMG_0056.jpg"
ren "IMG_0060.JPG" "IMG_0057.jpg"
ren "IMG_0061.JPG" "IMG_0058.jpg"
ren "IMG_0062.JPG" "IMG_0059.jpg"
ren "IMG_0063.JPG" "IMG_0060.jpg"
ren "IMG_0064.JPG" "IMG_0061.jpg"
ren "IMG_0065.JPG" "IMG_0062.jpg"
ren "IMG_0066.JPG" "IMG_0063.jpg"
ren "IMG_0067.JPG" "IMG_0064.jpg"
ren "IMG_0068.JPG" "IMG_0065.jpg"     :: Hier fehlt was
ren "IMG_0070.JPG" "IMG_0066.jpg"
ren "IMG_0071.JPG" "IMG_0067.jpg"     :: Hier fehlt was
ren "IMG_0073.JPG" "IMG_0068.jpg"
ren "IMG_0074.JPG" "IMG_0069.jpg"
ren "IMG_0075.JPG" "IMG_0070.jpg"
ren "IMG_0076.JPG" "IMG_0071.jpg"
ren "IMG_0077.JPG" "IMG_0072.jpg"
ren "IMG_0078.JPG" "IMG_0073.jpg"
ren "IMG_0079.JPG" "IMG_0074.jpg"
ren "IMG_0080.JPG" "IMG_0075.jpg"
ren "IMG_0081.JPG" "IMG_0076.jpg"
ren "IMG_0082.JPG" "IMG_0077.jpg"
ren "IMG_0083.JPG" "IMG_0078.jpg"
ren "IMG_0084.JPG" "IMG_0079.jpg"
ren "IMG_0085.JPG" "IMG_0080.jpg"
ren "IMG_0086.JPG" "IMG_0081.jpg"
ren "IMG_0087.JPG" "IMG_0082.jpg"
ren "IMG_0088.JPG" "IMG_0083.jpg"
ren "IMG_1057.JPG" "IMG_0084.jpg"
Drücken Sie eine beliebige Taste . . .

Mein derzeitiger Code:
Code:
@echo off
setlocal enabledelayedexpansion
set /a count=1
for /f "tokens=*" %%a in ('dir /b /on *.jpg') do (
	if /i !count! LSS 10 ( echo ren "%%a" "IMG_000!count!.jpg") else ( 
	if /i !count! LSS 100 ( echo ren "%%a" "IMG_00!count!.jpg") else ( 
	if /i !count! LSS 1000 echo ren "%%a" "IMG_0!count!.jpg"))
	set /a count+=1
)
pause

ot:
Gabs eigentlich nicht schon einmal so einen Fred? Ich hatte am Anfang nach dem gesucht, aber nicht gefunden. Kann aber auch sein, dass ich mir den nur einbilde.
 
Moin

Da ich gerade nicht Zuhause sitze, kann ich bei eurem Programm nicht helfen, sondern erst, wenn ich wieder Zuhause bin und mein Internet wieder funktioniert.


Aber ich kann mein Sortier-Programm in Aussicht stellen. Es sortiert alle jpg-Dateien mit einfachen Zahlen. Also 1, 2, 3, ...
Aber da ein Img davor zu schreiben, wäre nicht schwer.

Es funktioniert fehlerfrei, auch wenn ein Name bereits vorhanden ist. Der Nachteil ist aber, dass er in diesem Fall einfach alle Namen umbenennt und dann sortiert. So umgehe ich diesen Fehler. Das ist zwar unzweckmäßig, aber sicher.


Außerdem kann ich anbieten, ein Programm mit C# zuschreiben. Das würde viel schneller arbeiten, als ein Batch-Script, ist aber eben kein Batch ^^

Ist denke ich mal nicht schlimm, weil Batch nunmal seine Grenzen hat und die lassen sich, wenn überhaupt, nur durch viel Knobeln und kompliziertem umgehen lösen. Und das sehe ich persönlich nicht mehr als Lernen an.


Also sag bescheid, wenn du eins von beidem haben willst. Ist für mich kein Umstand.

Was den Batch-Scipt von euch angeht, werd ich mich dann auseinander setzen, wenn ich kann.

Ist ne spannende Frage, wie man das lösen kann ^^
 
Ein kleiner Zusatz vom Handy aus:

Man könnte die Zahlen auch in Anführungszeichen setzen, wenn der Bild-Name kreirt wird.
So bleibt es ein String und wird (hoffendlich) nicht missverstanden.

Der Name wird nicht geschrieben, sondern erst von Anführungszeichen befreit. Durch nichts ersetzen.

Und erst dann in die Datei schreiben.

Ist zwar ein Umweg, könnte aber funktionieren.

Gruß
 
Paladin007: Das einzige Problem sind die dämlichen Vornullen, denn da gibt es so einen kleinen "Bug" in der Batch Verarbeitung, der Windows glauben lässt, dass bestimmte Zahlen Oktalzahlen sind. Wenn das nicht wäre, wäre der ganze Kram ziemlich einfach.

btw: Es muss nicht unbedingt C sein (hat den Nachteil, dass man dann erstmal eine Entwicklungsumgebung mit Compiler und Linker einrichten müsste ;)), man könnte den ganzen Kram auch in irgendeiner anderen Scriptsprache wie z.B. VB oder JS schreiben, das wäre letztendlich auch zuverlässiger als die CMD Batch Sprache und würde vom System auch verstanden.
 
Das meinte ich ja. Wenn dann also 3 Nullen davor geschrieben werden sollen, dann werden sie halt so: "000" oder so: "0""0""0" geschrieben.
Dann sieht das so aus: IMG_"0""0""0"1.jpg
Mich würde es wundern, wenn er eine einzige Null falsch versteht^^

Allerdings will niemand den Namen so haben, aber da schafft das Abhilfe:

Code:
set name = IMG_"0""0""0"1.jpg
set name =%name :"=%

Danach sieht der Namen dann so aus, wie ihr das wollt.
Habs noch nicht getestet, werd mich mal in den Script einlesen und mal meine Idee zu verwirklichen.


Und ja, natürlich wäre ein Scriptsprache besser und mich störts auch, dass bei C# Net-Framework benötigt wird, aber ich kann im Moment nur C#^^
Vielleicht lese ich mich ja mal in VB ein. Dürfte ja nicht sonderlich anders aufgebaut sein, als C#.
Und Java-Script kenne ich überhaupt nicht, auch wenn es vielleicht ganz sinnvoll wäre. Mal schauen, was die Zukunft da so bringt^^



verborgener Text:
Code:
@echo off

dir /b /s |find /v /c "::" > zahl.txt
for /f %%i in (zahl.txt) do set zahl=%%i
del zahl.txt
set /a zahl-=2

set work=1
:work
if exist %work%-*.jpg (
    set /a work+=1
    goto work
) else (
    goto a
)

:a
set kon=1
for /f %%h in ('dir /b *.jpg') do call :kontroll %%h
goto kon_weiter

:kontroll
if %1==%kon%.jpg (
    if %kon%==%work% goto kon_weiter
    set /a kon+=1
) else (
    set kon=new
    goto :eof
)
goto :eof

:kon_weiter
set zähler=1
for /f "delims=" %%i in ('dir /b *.jpg') do call :name "%%i"
goto name_weiter

:name
ren %1 "%work%-%zähler%.jpg"
set /a zähler+=1
goto :eof

:name_weiter
set zähler=1
for /f "delims=" %%j in ('dir /b *.jpg') do call :name1 "%%j"
goto :eof

:name1
ren "%work%-%zähler%.jpg" "%zähler%.jpg"
set /a zähler=%zähler%+1
goto :eof

Um das dann mit IMG davor zu haben, müsste man nur diese Zeile:
Code:
ren "%work%-%zähler%.jpg" "%zähler%.jpg"
so schreiben:
Code:
ren "%work%-%zähler%.jpg" "IMG_%zähler%.jpg"



Vielleicht hilft es ja ^^
 
Das ist eigentlich nicht mehr das Problem, dass er alles als Oktalzahl versteht, sondern, dass er zufällig mal ein Bild "übersieht" und somit nicht umbenennt.
 
Achso...

Habs jetzt mal getestet und bei mir funktioniert es einwandfrei.

Und wenn ich mir den Code so anschaue, wüsste ich auch keine Ursache.


Was aber auch sein kann, ist, dass das Programm richtig ist, aber beim Bearbeiten Fehler passieren. Das Problem hatte ich auch schon. Es hat alles gestimmt und trotzdem gab es Fehler.


Ich teste das Programm mal bei meinen Rom-Bildern. Wenn der sich bei 666 Dateien nicht aufhängt, oder einen Fehler einbaut, weiß ich auch nicht weiter^^




PS:
Da fällt mir ein Problem ein, was ich bei meinem Code so umständlich gelöst habe:
Wenn eine Datei umbenannt wird und dieser Name bereits existiert, schmiert das ganze Programm ab.
Vielleicht solltest du das auch noch mit lösen.

ABer die Ursache für den Fehler kanns nicht sein, weil du ja nichts umbenannt hast.



Edit:
Habs getestet, ohne Fehler.
Alles ist so umbenannt worden, wie es soll.

Da weiß ich jetzt auch nicht mehr weiter, warum es bei dir nicht funktioniert.
 
Man könnte natürlich auch die Dateien nacheinander in ein temp Verzeichnis verschieben, dort umbenennen, in ein 2. temp verschieben. Wenn dann alle im 2. temp sind, kann man das alte leere und das erste temp löschen und das neue temp in den Originalnamen umbenennnen (beide Temps im selben Hauptordner wie das ursprüngliche Verzeichnis) - so würde man das Problem der schon vorhandenen Dateinamen umgehen ...



... oder sich ein Loch ins Knie bohren und Quark reinlaufen lassen, damit es nicht mehr so quietscht, oder sich einfach in den Fuß schießen, ist beides ungefähr gleich angenehm...
 
Naja, du musst ja auch daran denken, dass bei vielen Dateien das Programm dann sehr langsam wird und auch eine Menge Leistung beansprucht.

Man könnte doch auch einfach überprüfen, ob eine Datei den Namen hat, der irgendwo dann gegeben werden soll. Und daraus dann eine Schleife bauen, die einen neuen Namen erteilt und bevor der neue Name geschrieben wird, überprüft, ob der Name schon vorhanden ist.
Ist zwar kompliziert, würde den PC aber nicht so beanspruchen.
 
Ich hab grad den Thread nur so überflogen, weil ich von diesen Batch-Geschichten keine Ahnung hab.

Aber für solche Umbenennungs- und Sortieraktionen hab ich mal ein Tool irgendwo im Netz gefunden, das nennt sich "Bulk Rename Utility". Da wählt man die Dateien aus, die man "behandeln" möchte und kann damit allerhand anstellen, zum Beispiel: Nach dem 3. Zeichen des Dateinamens immer eine Bestimmte Zeichenfolge einfügen, bestimmte Sonderzeichen aus allen Dateinamen entfernen, nummerieren.... Man hat da enorm viele Möglichkeiten und kann da auch mit Regulären Ausdrücken arbeiten und alle möglichen Aktionen miteinander kombinieren.
 
Oben