Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Schleife in Batch-Datei funktioniert nicht wie gewollt, bitte um Hilfestellung

Frage Microsoft Windows Tools

Mitglied: panguu

panguu (Level 2) - Jetzt verbinden

09.10.2013 um 13:23 Uhr, 2320 Aufrufe, 11 Kommentare

Hallo miteinander,

ich verwende in einer Batch-Datei folgendes Schleifenkonstrukt:

:improcess
If Exist D:\test\*.pdf (
for %%f in ("D:\test\*.pdf") DO (
convert_program -option1 -option2 "%%f" D:\test\%date:~-2,2%%date:~-7,2%%date:~-10,2%_%time:~-11,2%%time:~-8,2%%time:~-5,2%%time:~-2,2%.tiff
)
)

Das bewirkt folgendes: es prüft das Verzeichnis D:\test auf vorhandene PDF-Dateien und falls dort welche vorhanden sind, werden diese mit einem extra Konvertierungsprogramm nach TIFF umgewandelt. Dabei generiere ich einen Dateinamen nach folgendem Schema:

131009_13184533.tiff

13 = aktuelles Jahr
10 = aktueller Monat
09 = heutiger Tag

13 = Uhrzeit/Stunden
18 = Uhrzeit/Minuten
45 = Uhrzeit/Sekunden
33 = Uhrzeit/Millisekunden

Ich habe die Millisekunden extra mitaufgenommen, weil ich verhindern wollte, dass Duplikate entstehen können. Aber das Problem ist, dass diese Schleife für alle generierten .TIFF Dateien dieselben Zeiten verwendet. Wenn ich z.B. in D:\test drei PDF-Dateien namens test1.pdf test2.pdf und test3.pdf liegen habe, dann generiert diese Schleife folgenden Output

131009_13213345.tiff

und zwar für alle 3 Dateien. Ich weiß das weil ich noch einen Zähler zum Testen genutzt habe und noch an den Dateinamen angefügt habe. Die %time% Variable scheint aber nur 1x eingelesen zu werden von der Schleife. Wie kann ich das verhindern und abändern, so daß Dateien entstehen nach diesem Muster:

131009_13213511.tiff (also um 13:21 Uhr und 35 Sekunden und 11 Millisekunden)
131009_13213869.tiff (also um 13:21 Uhr und 38 Sekunden und 69 Millisekunden)
131009_13214822.tiff (also um 13:21 Uhr und 48 Sekunden und 22 Millisekunden)

Bin für jeden Tip sehr dankbar.
Mitglied: bastla
09.10.2013 um 16:54 Uhr
Hallo panguu!

Vorweg: (Batch-) Code liest sich besser mit passender Formatierung ...

Dein Stichwort wäre "delayedExpansion" - ungetestet etwa:
01.
:improcess 
02.
for %%f in ("D:\test\*.pdf") DO ( 
03.
    setlocal enabledelayedexpansion     
04.
    convert_program -option1 -option2 "%%f" D:\test\!date:~-2,2!!date:~-7,2!!date:~-10,2!_!time:~-11,2!!time:~-8,2!!time:~-5,2!!time:~-2,2!.tiff 
05.
    endlocal 
06.
)
Die Prüfung per
If Exist D:\test\*.pdf (
kannst Du Dir sparen, da der "do"-Teil der Schleife ohnehin nur für vorhandene PDF-Dateien ausgeführt wird ...

Grüße
bastla
Bitte warten ..
Mitglied: panguu
09.10.2013 um 16:59 Uhr
Hallo bastla,

leider funktioniert's auch mit "setlocal enabledelayedexpansion" nicht noch 'ne andre Idee?
Bitte warten ..
Mitglied: bastla
09.10.2013, aktualisiert um 17:10 Uhr
Hallo panguu!

Was verstehst Du unter "funktioniert nicht"? Die Timestamps für die tiff-Dateinamen sollten auf jeden Fall passend erstellt werden ...

Anyhow - Du kannst es auch mit dieser Zeile (als Ersatz für die Zeilen 3 bis 5) versuchen:
call convert_program -option1 -option2 "%%f" D:\test\%%date:~-2,2%%%%date:~-7,2%%%%date:~-10,2%%_%%time:~-11,2%%%%time:~-8,2%%%%time:~-5,2%%%%time:~-2,2%%.tiff
Grüße
bastla
Bitte warten ..
Mitglied: panguu
09.10.2013 um 17:21 Uhr
Auch mit "call" funktioniert es nicht. Schau mal, ich hänge im Dateinamen am Ende noch eine Ziffer mitdran, das ist ein ganz normaler Zähler.

01.
set /a c=1 
02.
for %%f in ("D:\test\*.pdf") DO ( 
03.
 if not %errorlevel% == 0 goto :error 
04.
setlocal enabledelayedexpansion 
05.
call convert_program.exe -option1 -option2 "%%f" D:\test\%date:~-2,2%%date:~-7,2%%date:~-10,2%_%time:~-11,2%%time:~-8,2%%time:~-5,2%%time:~-2,2%_!c!.tiff 
06.
07.
endlocal
Meine generierten Dateinamen lauten dann:

131009_17164533_1.tiff
131009_17164533_2.tiff
131009_17164533_3.tiff
131009_17164533_4.tiff

Verstehst du was ich nun meine?
Bitte warten ..
Mitglied: bastla
09.10.2013, aktualisiert um 17:48 Uhr
Hallo panguu!

Kann ich trotzdem nicht nachvollziehen - bei mir sieht das so aus:
C:\Test>type MakeTIFF.cmd 
@echo off & setlocal 
for %%f in ("C:\test\*.pdf") DO ( 
    setlocal enabledelayedexpansion 
    echo convert_program -option1 -option2 "%%f" C:\test\!date:~-2,2!!date:~-7,2 
!!date:~-10,2!_!time:~-11,2!!time:~-8,2!!time:~-5,2!!time:~-2,2!.tiff 
    ping -n 1 localhost >nul 
    endlocal 
C:\Test>MakeTIFF.cmd 
convert_program -option1 -option2 "C:\test\1.pdf" C:\test\131009_17440514.tiff 
convert_program -option1 -option2 "C:\test\2.pdf" C:\test\131009_17440532.tiff 
convert_program -option1 -option2 "C:\test\3.pdf" C:\test\131009_17440546.tiff 
 
C:\Test>
Du könntest es noch mit einem Unterprogramm versuchen:
01.
:improcess 
02.
for %%f in ("D:\test\*.pdf") DO call :ProcessFile "%%f" 
03.
goto :eof 
04.
 
05.
:ProcessFile 
06.
convert_program -option1 -option2 %1 D:\test\%date:~-2,2%%date:~-7,2%%date:~-10,2%_%time:~-11,2%%time:~-8,2%%time:~-5,2%%time:~-2,2%.tiff 
07.
goto :eof
Grüße
bastla
Bitte warten ..
Mitglied: panguu
10.10.2013 um 10:01 Uhr
dein oberes Beispiel funktioniert nur deswegen, weil du auch
01.
ping -n 1 localhost >nul
verwendet hast. Wenn du das auskommentierst, dann wirst du dasselbe Ergebnis wie ich erhalten.

Also könnte ich durch diesen kleinen Workaround-Trick mit dem ping Befehl eine kleine Zeitverzögerung einbauen, das würde klappen, ja.
Danke dir hierfür. Auch wenn dadurch mein Problem behoben wurde, würde mich ordnungshalber trotzdem interessieren, warum das so innerhalb der Schleife abgearbeitet wird (also in einem Stück, zur exakt derselben Zeit).

Kennt ihr vielleicht noch eine elegantere/saubere Lösung zu diesem Phänomen?

Bastla, den unteren Teil habe ich mir jetzt gar nicht erst angeschaut mit den Unterprogrammen, da das obere ja bereits funktioniert hat. Trotzdem auch hierfür danke.

Grüße,
Pangu
Bitte warten ..
Mitglied: bastla
10.10.2013 um 10:20 Uhr
Hallo panguu!
Wenn du das auskommentierst, dann wirst du dasselbe Ergebnis wie ich erhalten.
Mit dem "ping" wird ja nur die Zeit für den Programmablauf simuliert (der "Aufruf" besteht in meinem Beispiel ja nur aus einem "echo" und davon gehen sich in einer Hundertstelsekunde einige aus), um zeigen zu können, dass die Timestamp-Erstellung innerhalb der Schleife sehr wohl unterschiedliche Werte (Zeiten) ergibt.
warum das so innerhalb der Schleife abgearbeitet wird (also in einem Stück, zur exakt derselben Zeit).
In einem Stück abgearbeitet wird nur die Variablenauflösung (wenn nicht "delayed" wird). Vermutlich ist einfach Dein Programm sehr schnell ...

Grüße
bastla
Bitte warten ..
Mitglied: panguu
10.10.2013 um 11:06 Uhr
Hallo bastla, ich hab gerade noch etwas herumexperimentiert. Wenn ich deinen obigen Code
01.
C:\Test>type MakeTIFF.cmd  
02.
@echo off & setlocal  
03.
for %%f in ("C:\test\*.pdf") DO (  
04.
    setlocal enabledelayedexpansion  
05.
    echo convert_program -option1 -option2 "%%f" C:\test\!date:~-2,2!!date:~-7,2  
06.
!!date:~-10,2!_!time:~-11,2!!time:~-8,2!!time:~-5,2!!time:~-2,2!.tiff  
07.
    ping -n 1 localhost >nul  
08.
    endlocal  
09.
) 
betrachte, dann habe ich festgestellt, daß du statt %date% !date! verwendest, also statt dem Prozentzeichen (%) ein Ausrufezeichen (!). Und genau deswegen klappt es oder klappt es nicht. Es liegt also nicht wie vorhin von mir vermutet an dem "Ping"-Befehl, sondern ich hatte erstmal von dir abgeschrieben und ! verwendet. Und dann in meinem Code hatte ich wieder die Prozentzeichen drinstehen. Und beim Prozentzeichen scheint das enabledelayedexpansion nicht zu greifen. Ich habe also daraufhin den Ping-Befehl wieder gelöscht und verwende überall für meine date und time Variablen das Ausrufezeichen. Damit krieg ich nen Zeitstempel der einzelnen Datein mit 3 Millisekunden, das passt!

Was ist denn nun der Unterschied zwischen Prozentzeichen und Ausrufezeichen bei Variablen?
Bitte warten ..
Mitglied: pieh-ejdsch
10.10.2013 um 12:27 Uhr
moin pangu,

wenn Du wärend der Schleifenabrbeitung eine Ausgabe in die Console erzeugst, könnte es auslangen diese Millisekunde zu überbrücken.

erster Test in der CMD Line wieviele Zeilen je Millisekunde
> cmd /von/c "for /l %i in (1 1 10000) do @(if !test! neq !time:~-2! echo %i !time:~-2!)&set "test=!time:~-2!"" 
1 34 
15 35 
220 36 
437 37 
654 38 
872 39 
1090 40 
1306 41 
1526 42 
1745 43 
1963 44 
2185 45 
2409 46 
3879 52 
4352 54 
4575 55 
4800 56 
5025 57 
5498 59 
5723 60 
5948 61 
6172 62 
6396 63 
6621 64 
6840 65 
7563 68 
7788 69 
8011 70 
8235 71 
8459 72 
8684 73 
8907 74 
9131 75 
9355 76 
9578 77 
9799 78
Da nun hier auch eine Ausgabe erfolgt, aber die Millisekunde zum Unterschied nicht erreicht wird ist die Bearbeitung zu schnell.
Ein Wert geht sogar über 470 potentielle Zeilen, obwohl je zeile zwei Variablen dargestellt werden müssen und eine erstellt wird.
10000 zu 34 Millisekunden passt da auch noch nicht.
Eine Ausgabe reicht also nicht. Aber eine Ausgabe zu Dursuchen könnte dazu langen:
> cmd /von/c "for /l %i in (1 1 500) do @echo X|find "u" &(if !test! neq !time:~-2! echo %i  !time:~-2!) &set "test=!time:~-2!""|find /c /v "" 
500
Da jetzt find (sogar ohne Ausgabe) etwas zu tun hat, verzögert das um ca 1 Millisekunde

Durch Verlegen der seperaten CMD instanz gibt es auch eine Verzögerung von je einer Millisekunde.
01.
 type=plain> 
02.
> for /l %i in (1 1 20) do @cmd /von /c echo %i  !time:~-2! 
03.
1  22 
04.
2  23 
05.
3  24 
06.
4  25 
07.
5  26 
08.
6  28 
09.
7  29 
10.
8  30 
11.
9  31 
12.
10  32 
13.
11  33 
14.
12  34 
15.
13  35 
16.
14  36 
17.
15  37 
18.
16  38 
19.
17  39 
20.
18  40 
21.
19  41 
22.
20  42
Vllt ist die bessere Alternative eine Temporäre vbs zu schreiben, welche eine Millisekunde wartet.

Gruß Phil
Bitte warten ..
Mitglied: bastla
10.10.2013 um 13:24 Uhr
Hallo panguu!
Was ist denn nun der Unterschied zwischen Prozentzeichen und Ausrufezeichen bei Variablen?
Falls ich das noch nicht erwähnt haben sollte: "delayedExpansion"

Schau Dir einmal das einschlägige Tutorial zur FOR-Schleife von Friemler an ...

Grüße
bastla
Bitte warten ..
Mitglied: panguu
10.10.2013, aktualisiert um 15:09 Uhr
@phil, danke für deinen ausführlichen Beitrag. Jedoch habe ich durch Bastlas Hilfe herausgefunden, wo das ursprüngliche Problem war. "delayedExpansion" ist tatsächlich das richtige Schlagwort hierfür.

@bastla: Vielen herzlichen Dank für die Verlinkung dieses tollen Tutorials, das Friemler hier freundlicherweise zur Verfügung stellt. Sehr nettes Tutorial *daumen_Hoch!*. Da wird genau dieser Fall erörtert und beantwortet damit meine vorherige Frage zum Unterschied von Prozent- und Ausrufezeichen.

Durch ENABLEDELAYEDEXPANSION wird die verzögerte Variablenerweiterung aktiviert. Dadurch, dass ein Variablenname in Ausrufezeichen statt in Prozentzeichen eingeschlossen ist, wird dem Befehlsinterpreter mitgeteilt, diesen Variablennamen erst bei Ausführung des Befehls durch seinen Wert zu ersetzen, der durch den vorhergehenden SET-Befehl gesetzt wurde

Vielen Dank! Problem wurde als gelöst markiert.
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
Ä in batch Datei (12)

Frage von BergEnte zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (20)

Frage von Xaero1982 zum Thema Microsoft ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Festplatten, SSD, Raid
M.2 SSD wird nicht erkannt (14)

Frage von uridium69 zum Thema Festplatten, SSD, Raid ...