legolegolas
Goto Top

Batch für spezifisches Kopieren von JPG-Dateien und zusätzlichem Umbenennen nach Texteingabe und Reihenfolge

Hallo Experten

Ich habe eine stets wiederkehrende Arbeit am PC, die ich gerne mit einem Batch erledigen würde - nur fehlt mir leider das Wissen dazu, bzw. scheitere ich schon bei den Ansätzen und die Aufgabe ist zu spezifisch um im Netz ein schon vorhandenes Script zu finden.

Folgendes Szenario:

Auf Laufwerk: Z habe ich einen Ordner "Bilder" und darin beliebig viele Unterordnern (nur 1 Level) mit beliebigen Namen in denen beliebig viele Bilder im jpg-Format vorhanden sind.

Nun möchte ich jeweils nur das erste JPG (nach Namen sortiert) aus allen Unterordnern in der richtigen Reihenfolge in einen neuen Ordner "Z: Bilder neu" kopieren und umbenennen.

Vom Ablauf her habe ich mir das so vorgestellt:

Ich starte den Batch und bekomme eine Texteingabe-Aufforderung - schreibe z.B. "Sommer 2014" und das Script starten nun beim ersten Unterordner (nach Name sortiert) und kopiert das erste JPG nach "Z: Bilder neu" (schon erstellt) in einen neuen Unterordner mit dem Namen der Texteingabe "Sommer 2014" (soll einmalig erstellt werden) und dem Dateinamen "Sommer 2014 001".
Das erste Bild aus dem 2. Unterordner sollte dann "Sommer 2014 002" heißen usw. bis alle Unterordner in "Z: Bilder" abgearbeitet sind.


Optional: Was ist zu ändern wenn ich z.B. nur das 20. Bild kopieren möchte.
Welche Ergänzung braucht es wenn die Bilder z.T. tiefer in der Ordnerstruktur (unterschiedlich) angesiedelt sind.

Beispiel:
Anstatt
Z: Bilder\August01\(JPG-Dateien)
wäre da z.B.
Z: Bilder\August01(ohne JPG-Dateien)\neu\(JPG-Dateien)


Ich wäre für Eure Hilfe dankbar.

LG

Legolegolas

Content-Key: 247202

Url: https://administrator.de/contentid/247202

Ausgedruckt am: 29.03.2024 um 06:03 Uhr

Mitglied: rubberman
Lösung rubberman 23.08.2014, aktualisiert am 24.08.2014 um 02:52:52 Uhr
Goto Top
Hallo Legolegolas, willkommen im Forum.

Den ersten Teil deiner Frage + dem Zusatz des wievielten Bilds könnte man etwa so lösen:
@echo off &setlocal

set "copyFrom=Z:\Bilder"  
set "copyTo=Z:\Bilder neu"  
set "nthPicture=1"  

:inpLoop
set "basename="  
set /p "basename=Name: "  
if not defined basename goto inpLoop
setlocal EnableDelayedExpansion
for /f delims^=\/:*?^<^>^|^" %%i in ("!basename!") do if "!basename!" neq "%%i" (endlocal &goto inpLoop)  
if "!basename:~-1!"==" " (endlocal &goto inpLoop)  
endlocal

md "%copyTo%\%basename%" || goto inpLoop  
set "copyTo=%copyTo%\%basename%"  

set /a "n=1000"  
for /f "delims=" %%i in ('dir /ad /b /on "%copyFrom%\*"') do (  
  for /f "tokens=1* delims=:" %%j in ('dir /a-d /b /on "%copyFrom%\%%i\*.jpg"^|findstr /n .') do (  
    if "%%j"=="%nthPicture%" (  
      set /a "n += 1"  
      setlocal EnableDelayedExpansion
      for %%l in (!n:~-3!) do (
        copy "!copyFrom!\%%i\%%k" "!copyTo!\!basename! %%l.jpg"  
      )
      endlocal
    )
  )
)

Welche Ergänzung braucht es wenn die Bilder z.T. tiefer in der Ordnerstruktur (unterschiedlich) angesiedelt sind.
Nach was sollte dann sortiert werden? Nach dem Name des Unterverzeichnisses im ersten Level?

Grüße
rubberman

Edit: Zeile 16 und 17 getauscht
Mitglied: Legolegolas
Legolegolas 23.08.2014 um 17:01:29 Uhr
Goto Top
Rubberman - du bist gut! Ich habe dir gleich mal ein Karma-Pluspunkt gut schreiben lassen, denn das Script funktioniert super. Du hast das exakt nach Wunsch kreiert. Besten Dank dafür.

Wegen dem Zusatz - ein mögliches Szenario:

Ich starte das Script - gebe den Begriff ein (funktioniert alles bereits hervorragend) und das Script geht zum ersten Unterordner. Falls da JPG-Dateien darin vorhanden sind folgt er dem Scriptablauf - falls keine JPG-Dateien in diesem Unterordner sind, springt das Script eine Ordnerstruktur tiefer - d.h. in diesem Level sind keine JPG-Dateien, dafür ein weiterer (und nur 1) Ordner in den das Script nun folgt und wieder untersucht, ob Bilder vorhanden sind und falls nicht geht es wieder eine Ordnerstruktur tiefer. In jedem Level hat es entweder die Bilder oder 1 weiterer Unterordner. Irgendwann kommen die Bilder und das Script kopiert die gewünschte JPG-Datei und benennt sie der Texteingabe und Reihenfolge entsprechend und folgt dem weiteren Ablauf.
Sortierung ist in allen Fällen nach Namen.


Klasse Forum

LG

Legolegolas
Mitglied: rubberman
Lösung rubberman 23.08.2014, aktualisiert am 24.08.2014 um 02:52:58 Uhr
Goto Top
Hallo Legolegolas,

dann sollten die benötigten Änderungen marginal sein ...
@echo off &setlocal

set "copyFrom=Z:\Bilder"  
set "copyTo=Z:\Bilder neu"  
set "nthPicture=1"  

:inpLoop
set "basename="  
set /p "basename=Name: "  
if not defined basename goto inpLoop
setlocal EnableDelayedExpansion
for /f delims^=\/:*?^<^>^|^" %%i in ("!basename!") do if "!basename!" neq "%%i" (endlocal &goto inpLoop)  
if "!basename:~-1!"==" " (endlocal &goto inpLoop)  
endlocal

md "%copyTo%\%basename%" || goto inpLoop  
set "copyTo=%copyTo%\%basename%"  

set /a "n=1000"  
for /f "delims=" %%i in ('dir /ad /b /on "%copyFrom%\*"') do (  
  for /f "tokens=1* delims=:" %%j in ('dir /a-d /b /on /s "%copyFrom%\%%i\*.jpg"^|findstr /n .') do (  
    if "%%j"=="%nthPicture%" (  
      set /a "n += 1"  
      setlocal EnableDelayedExpansion
      for %%l in (!n:~-3!) do (
        copy "%%k" "!copyTo!\!basename! %%l.jpg"  
      )
      endlocal
    )
  )
)

Grüße
rubbermann
Mitglied: Legolegolas
Legolegolas 23.08.2014 um 23:22:54 Uhr
Goto Top
Funktioniert einwandfrei - spitzenmäßig.

Ich danke dir vielmals, das ist eine große Arbeitserleichterung für mich.
Ich werde versuche das Script auch zu begreifen.

Ebenfalls ein Dank an die Forumsadministration für die Möglichkeit hier Fragen stellen zu können.

LG

Legolegolas
Mitglied: rubberman
rubberman 23.08.2014 um 23:38:16 Uhr
Goto Top
Ich werde versuche das Script auch zu begreifen.
Das ist sehr lobenswert! Falls du über etwas stolperst, das du nicht verstehst, frage gerne nach.

Grüße
rubberman
Mitglied: Yunkyard
Yunkyard 25.08.2014 um 17:34:02 Uhr
Goto Top
Hallo erst mal,

Das Script ist cool. So etwas in der Art suche ich auch schon lange.

Was ist zu tun wenn man ALLE Bilder im Ordner umbenennen will?

Gruß Gebhard
Mitglied: rubberman
rubberman 25.08.2014 um 20:18:17 Uhr
Goto Top
Hallo Yunkyard.

Was ist zu tun wenn man ALLE Bilder im Ordner umbenennen will?
Da das nicht der Anforderung von Legolegolas entspricht, auf jeden Fall einen eigenen Thread aufmachen und dann genauer erklären, was wie umbenannt werden soll (alle rekursiv, alle nur im ersten Level, wie viele Dateien maximal wegen der vorangestellten Nullen etc.).

Grüße
rubberman
Mitglied: Legolegolas
Legolegolas 29.08.2014 aktualisiert um 14:52:47 Uhr
Goto Top
Zitat von @rubberman:

Das ist sehr lobenswert! Falls du über etwas stolperst, das du nicht verstehst, frage gerne nach.

Grüße
rubberman


Nehme ich gerne an face-wink

Immer diese Ausnahmen in der Regel...
...also, ich hätte da noch ein weitere Option die mir selber nicht gelingt und ich getraue mich nicht da in deinem Part herum zu experimentieren, weil ich es nur ansatzweise verstehe. Zumindest habe ich das Script noch laienhaft erweitert - rar-Dateien entpacken (übernommen von winrar) - dann dein genialer Teil - und jpg-Dateien Auflösung verkleinern mit Irfanview mit erneutem Speichern in den "finalen" Ordner "Cover".

Und eben diese Ausnahmen - ich bräuchte noch eine Set-Einstellung für den Anfang der Aufzählung (kann sein, dass ich z.B. mit 007 anstatt mit 001 anfangen muss)

(Anmerkung - Bitte keinen Lachkrampf wegen dem Script bekommen - ich bin Anfänger)
@echo off &setlocal

set dirA=Z:\Arbeitsplatz\Bilderarchiv
set dirE=Z:\Arbeitsplatz\Bilder\
set dirC=Z:\Arbeitsplatz\Bilderarchiv2\
cd %dirA%
set path="C:\Program Files\WinRAR\";%path%  
All files in %dirA% to be uncompressed
FOR %%i IN (*.rar) do (
unrar e -ad "%%~ni.rar" "%dirE%"  
move "%%~ni.rar" "%dirC%"  
echo completed uncompressing "%%i" and moved archives or archive to "%dirC%"  
)
goto eof

:eof

endlocal

echo.
echo "Task Completed"  
echo.



@echo off &setlocal

set "copyFrom=Z:\Arbeitsplatz\Bilder"  
set "copyTo=Z:\Arbeitsplatz\Bilderneu"  
set "nthPicture=1"  

:inpLoop
set "basename="  
set /p "basename=Name: "  
if not defined basename goto inpLoop
setlocal EnableDelayedExpansion
for /f delims^=\/:*?^<^>^|^" %%i in ("!basename!") do if "!basename!" neq "%%i" (endlocal &goto inpLoop)  
if "!basename:~-1!"==" " (endlocal &goto inpLoop)  
endlocal

md "%copyTo%\%basename%" || goto inpLoop  
set "copyTo=%copyTo%\%basename%"  

set /a "n=1000"  
for /f "delims=" %%i in ('dir /ad /b /on "%copyFrom%\*"') do (  
  for /f "tokens=1* delims=:" %%j in ('dir /a-d /b /on "%copyFrom%\%%i\*.jpg"^|findstr /n .') do (  
    if "%%j"=="%nthPicture%" (  
      set /a "n += 1"  
      setlocal EnableDelayedExpansion
      for %%l in (!n:~-3!) do (
        copy "!copyFrom!\%%i\%%k" "!copyTo!\!basename! %%l.jpg"  
      )
      endlocal
    )
  )
)


@echo off

set path="C:\Program Files (x86)\IrfanView\";%path%  

i_view32.exe z:\Arbeitsplatz\Bilderneu\%basename%\*.jpg /resize=(400,0) /aspectratio /resample /convert=z:\Arbeitsplatz\Cover\%basename%\*.jpg

rd /s /Q z:\Arbeitsplatz\Bilderneu
rd /s /Q z:\Arbeitsplatz\Bilder
md z:\Arbeitsplatz\Bilderneu
md z:\Arbeitsplatz\Bilder
@pause

LG

Legolegolas


Anmerkung: Ich habe dein erstes Script verwendet, weil ich den Script-Teil von Winrar so umgeschrieben habe, dass es die Dateien immer in einen Ordner packt - egal wie die Struktur im Archiv ist.
Mitglied: rubberman
Lösung rubberman 29.08.2014 aktualisiert um 20:27:28 Uhr
Goto Top
Hallo Legolegolas.

Und eben diese Ausnahmen - ich bräuchte noch eine Set-Einstellung für den Anfang der Aufzählung (kann sein, dass ich z.B. mit 007 anstatt mit 001 anfangen muss)

Eigentlich gibt es diese Einstellung bereits. Der initiale Wert der Variablen n ist hier entscheidend. Im Beispiel ist er 1000. Beim ersten Schleifendurchlauf wird er auf 1001 erhöht, beim zweiten auf 1002, etc. Für den Name der kopierten Datei werden dann jeweils die letzten 3 Ziffern herangezogen (auf diese Weise kommt man zu den vorangestellten Nullen).

Am Ende ist es also ganz einfach: Wenn du mit 007 starten willst, dann ist der Anfangswert für n eben 1006 statt 1000. Das war's schon face-wink

Grüße
rubberman
Mitglied: Legolegolas
Legolegolas 29.08.2014 um 20:27:14 Uhr
Goto Top
Danke - das ist wieder ein Schritt Richtung Glückseligkeit face-wink

Ich taste mich nach und nach an die Feinheiten deines Scripts - also für mich Anfänger doch ziemlich anspruchsvoll. Ich kannte bis dato nur "Autohotkey-Programmierung" ein wenig.
Mitglied: Legolegolas
Legolegolas 26.02.2016 um 03:33:06 Uhr
Goto Top
Ich hätte da zu später Stunde noch eine Ergänzungsfrage zum obigen Batch.

Es werden ja Anfangs Bilder aus diversen Ordnern verschoben. Das funktioniert alles wunderbar, außer eben wenn ein "!" im Ordnernamen steht und das kommt leider öfters vor. CMD bringt mir dann eine Fehlermeldung: "Das System kann die angegebene Datei nicht finden."

Wie lässt sich das umgehen?
Mitglied: rubberman
rubberman 26.02.2016 um 18:54:49 Uhr
Goto Top
Hallo Legolegolas,

das lässt sich umgehen, indem man Variablenzuweisungen bei ausgeschalteter verzögerter Variablenerweiterung vornimmt und die Verarbeitung der Variablen mit eingeschalteter verzögerter Variablenerweiterung.
Beispiele zur Verdeutlichung:

funktioniert nicht
@echo off
setlocal DisableDelayedExpansion

md "test~ohneAusrufezeichen"  
md "test~mit!"  

setlocal EnableDelayedExpansion
for /d %%i in ("test~*") do (  
  set "foldername=%%i"  
  echo !foldername!
)
endlocal

rd "test~ohneAusrufezeichen"  
rd "test~mit!"  

pause



funktioniert
@echo off
setlocal DisableDelayedExpansion

md "test~ohneAusrufezeichen"  
md "test~mit!"  

for /d %%i in ("test~*") do (  
  set "foldername=%%i"  
  setlocal EnableDelayedExpansion
  echo !foldername!
  endlocal
)

rd "test~ohneAusrufezeichen"  
rd "test~mit!"  

pause

Grüße
rubberman
Mitglied: Legolegolas
Legolegolas 26.02.2016 aktualisiert um 22:43:37 Uhr
Goto Top
Hallo Rubberman

Danke für das Beispiel. Ich bin jetzt schon 2 Stunden daran das irgendwie in mein Script einzubauen und es klappt einfach nicht.

Wenn ich das richtig verstanden habe muss ich 2 Zeilen richtig positionieren:
- setlocal DisableDelayedExpansion
- setlocal EnableDelayedExpansion

Ich habe es versucht - am guten Willen fehlt es nicht. Wo auch immer ich die 2 Zeilen einfüge es kommt nicht so wie es sollte.


Deinem Ursprung-Script habe ich ja Anfangs noch einen Winrar-Code angefügt und am Ende kommt die Bildverkleinerung per Irfanview zum Zuge.
Jetzt bin ich mir eben nicht sicher, ob ich dann "DisableDelayedExpansion" schon bei der Generierung der Ordner einfügen muss.
Mir geht beim Batch-Schreiben einfach nicht der Knopf auf. Ich habe mich jetzt deshalb längere Zeit nicht mehr damit beschäftigt und dies ist ein neuer Anfang und es harzt wieder - ich hänge mich immer an Kleinigkeiten auf.

Hier mal mein momentanes Script und die Bitte: "Kannst du mir zeigen wo ich die Zeilen einfügen muss"

@echo off &setlocal

Ren "Z:\Arbeitsplatz\Bilderarchiv\*.cbr" *.rar  

set dirA=Z:\Arbeitsplatz\Bilderarchiv
set dirE=Z:\Arbeitsplatz\Bilder\
set dirC=Z:\Arbeitsplatz\Bilderarchiv2\
cd %dirA%
set path="C:\Program Files\WinRAR\";%path%  
rem All files in %dirA% to be uncompressed
FOR %%i IN (*.rar) do (
unrar e -ad "%%~ni.rar" "%dirE%"  
move "%%~ni.rar" "%dirC%"  
echo completed uncompressing "%%i" and moved archives or archive to "%dirC%"  
)
goto eof

:eof

endlocal

echo.
echo "Task Completed"  
echo.



@echo off &setlocal

set "copyFrom=Z:\Arbeitsplatz\Bilder"  
set "copyTo=Z:\Arbeitsplatz\Bilderneu"  
set "nthPicture=1"  

:inpLoop
set "basename="  
set /p "basename=Name: "  
if not defined basename goto inpLoop
setlocal EnableDelayedExpansion
for /f delims^=\/:*?^<^>^|^" %%i in ("!basename!") do if "!basename!" neq "%%i" (endlocal &goto inpLoop)  
if "!basename:~-1!"==" " (endlocal &goto inpLoop)  
endlocal

md "%copyTo%\%basename%" || goto inpLoop  
set "copyTo=%copyTo%\%basename%"  

set /a "n=1000"  
for /f "delims=" %%i in ('dir /ad /b /on "%copyFrom%\*"') do (  
  for /f "tokens=1* delims=:" %%j in ('dir /a-d /b /on "%copyFrom%\%%i\*.jpg"^|findstr /n .') do (  
    if "%%j"=="%nthPicture%" (  
      set /a "n += 1"  
      setlocal EnableDelayedExpansion
      for %%l in (!n:~-3!) do (
        copy "!copyFrom!\%%i\%%k" "!copyTo!\!basename! %%l.jpg"  
      )
      endlocal
    )
  )
)


@echo off

set path="C:\Program Files (x86)\IrfanView\";%path%  

i_view32.exe z:\Arbeitsplatz\Bilderneu\%basename%\*.jpg /resize=(400,0) /aspectratio /resample /convert=z:\Arbeitsplatz\Cover\%basename%\*.jpg

rd /s /Q z:\Arbeitsplatz\Bilderneu
rd /s /Q z:\Arbeitsplatz\Bilder
md z:\Arbeitsplatz\Bilderneu
md z:\Arbeitsplatz\Bilder


@pause



LG

Legolegolas
Mitglied: rubberman
rubberman 27.02.2016 um 12:18:18 Uhr
Goto Top
Wenn ich das richtig verstanden habe muss ich 2 Zeilen richtig positionieren:
- setlocal DisableDelayedExpansion
- setlocal EnableDelayedExpansion
Hast du nur zur Hälfte verstanden. Das endlocal spielt eine genauso große Rolle. Damit wird die vorher mit setlocal erzeugte Subumgebung wieder beendet.

Schmeiß mal die ganzen ECHO OFFs aus deinem Code (auch die sowieso sinnlosen mitten im Script). Und schau dir dann mal an, wo der Fehler auftaucht.

Grüße
rubberman