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

Problem For-Schleife in Batch

Frage Entwicklung Batch & Shell

Mitglied: goodbytes

goodbytes (Level 2) - Jetzt verbinden

13.06.2013 um 13:34 Uhr, 1947 Aufrufe, 18 Kommentare

Hallo,
ich bin bald am verzweifeln. Mit einer Batch bearbeite ich alle jpg`s in einem Verzeichnis. Es soll jede Datei angefasst werden, mittels ZBarimg der Barcode darin gelesen werden und die Datei anschließend umbenannt werden. Es hatte auch schon funktioniert. Auf einen Schlag geht es nicht mehr.

Folgende Zeile sollte den Barcode aus jeder Datei auslesen und in eine Variable schreiben:

01.
For /F "tokens=2 delims=':'" %%i in ('zbarimg "%1"') do Set "NEUERNAME=%%i"
Trennzeichen soll der Doppelpunkt sein (der ausgelesene Code sieht so aus: CODE-128:M2013-007826).

Wenn ich statt "%1" einen Dateinamen eingebe klappt es wunderbar.

Wo liegt da der Fehler?

Torsten
Mitglied: colinardo
13.06.2013, aktualisiert um 14:50 Uhr
hallo Torsten,
lass mal die einfachen Anführungszeichen um den Doppelpunkt bei delims=':' weg. Sollte dann so aussehen delims=:
Grüsse Uwe
Bitte warten ..
Mitglied: Endoro
13.06.2013 um 14:50 Uhr
Hallo Torsten,

versuch es mal so:
01.
For /F "tokens=2 delims=:" %%i in ('zbarimg "%~1"') do Set "NEUERNAME=%%i"
Gruss!
Bitte warten ..
Mitglied: goodbytes
13.06.2013 um 16:41 Uhr
Hallo,
nein, der Fehler lag woanders. Ich hatte nicht erwähnt, dass die Batch über ein vbs-Script gestartet wird, welches immer einen Dateinamen als Parameter übergibt:

01.
oShell.Run "C:\Windows\System32\cmd.exe /c " & "D:\Barcode.cmd " & GetFileName_From_FilePath(file), 0, vbTrue
Der Fehler lag tatsächlich in diesem Script, die Batch war in Ordnung.

Trotzdem danke für eure Antworten !!!

Gruß
Torsten
Bitte warten ..
Mitglied: bastla
13.06.2013 um 19:26 Uhr
Hallo TorstenB!
die Batch war in Ordnung.
... aber hinsichtlich der von colinardo angesprochenen Apostrophe definitiv suboptimal - ein Apostroph davon kann sinnvoll sein (falls er tatsächlich als Delimiter gelten soll), 2 brauchst Du aber sicher nicht, da die "delims"-Angabe ohnehin nicht als String, sondern als Folge einzelner Trennzeichen interpretiert wird.

Grüße
bastla
Bitte warten ..
Mitglied: goodbytes
17.06.2013 um 11:27 Uhr
Hallo Bastla,
alles klar, vielen Dank für die Info.

Vielen Dank auch an Uwe und Endoro !!!

Gruß
Torsteb
Bitte warten ..
Mitglied: goodbytes
19.01.2016, aktualisiert um 11:40 Uhr
Hallo,
der Beitrag ist mittlerweile schon etwas älter und es hatte auch bestens funktioniert.
Mittlerweile haben sich aber auch viele Änderungen ergeben und in der Batch soll eigentlich nur noch der reine Barcode ausgelesen und zurück an das vbs-Script übergeben werden.
Nun meine Frage. Ich kann natürlich einen Befehl direkt in der vbs an die cmd übergeben:
01.
Dim objWshShell: Set objWshShell = WScript.CreateObject("WScript.Shell") 
02.
objWshShell.Run("cmd.exe /k " & "for /F " & """tokens=2 delims=':'""" & " %%i in ('zbarimg Test-Datei.jpg') do set String= %%i")
(Hier ist aber noch irgendein Syntax-Fehler drin.)
Wie bekomme ich den Wert der Variable "String" zur weiteren Verarbeitung in die vbs-Datei? Vielleicht macht es auch mehr Sinn nur den reinen Programmaufruf ('zbarimg Test-Datei.jpg')an die Kommandozeile zu übergeben und den Sting dann in der vbs zu "zerpflücken" um nur den Teilstring zu bekommen?

Hier zur Info noch der funktionierende Aufruf in einer Batch-Datei:
01.
for /F "tokens=2 delims=':'" %%i in ('zbarimg "Test-Datei.jpg"') do set "String=%%i" 
02.
echo Wert: %String% 
03.
pause
Danke schon mal im Voraus!!!
Torsten
Bitte warten ..
Mitglied: colinardo
LÖSUNG 19.01.2016, aktualisiert um 12:22 Uhr
Hallo Torsten,
mach das nicht so umständlich. Es gibt da eine viel cleanere Methode den Output eines DOS-Befehls in VBS abzufragen:
01.
Set objShell = CreateObject("Wscript.Shell") 
02.
 
03.
'Befehl ausführen 
04.
Set oExec = objShell.Exec("cmd /c zbarimg Test-Datei.jpg") 
05.
 
06.
'Warte darauf das der Befehl beendet wurde 
07.
Do While oExec.Status = 0 
08.
     WScript.Sleep 100 
09.
Loop 
10.
 
11.
' StdOut auslesen 
12.
out = "" 
13.
Do While Not oExec.StdOut.AtEndOfStream 
14.
   out = out & oExec.StdOut.ReadAll 
15.
Loop 
16.
 
17.
' zweites Token der ersten Zeile ausgeben, Delimiter ist ":" 
18.
MsgBox Split(out,":",-1,1)(1)
Ich gehe hier nur einmal von einer Ausgabe-Zeile aus. Wenn die Ausgabe des Befehls anderst aussieht musst du sie hier posten dann passe ich es dir noch an.

Grüße Uwe

p.s. Diese Methode hatte ich dir hier auch schon mal gepostet
http://www.administrator.de/frage/vbs-variable-parameter-externes-progr ...
Bitte warten ..
Mitglied: goodbytes
19.01.2016 um 12:24 Uhr
Hallo Uwe,
oh, sorry, stimmt, du hast es mir schon einmal gepostet... Asche auf mein Haupt...

Ich danke dir auf jeden Fall, es funktioniert jetzt bestens so!
Einen schönen Tag wünsche ich dir noch!

Gruß
Torsten
Bitte warten ..
Mitglied: goodbytes
20.01.2016 um 23:53 Uhr
Bisher war ich der Meinung, dass ich von dem Tool zur Barcode-Erkennung nur einen String zurück bekomme. Nun hat sich herausgestellt, dass wenn zufällig andere Barcodes enthalten sind, diese getrennt mit einem Zeilenumbruch (vbCrlf) mit ausgegeben werden.

So also:
Code128:182883839
Code128:049483738
Code128:B2016-12345
Code128:9438375zu
Code128:E2016-12345
usw.

Nun muss ich also noch den gesamten String durchsuchen nach meinem Barcode, der mit "B20" oder "E20" beginnt suchen und nur genau diesen String "B2016-12345" bekommen. Ist bisher nicht aufgefallen, da immer nur ein Barcode vorhanden war...
Wäre auch zu einfach gewesen... Naja, was solls, mal sehen...

Gruß
Torsten
Bitte warten ..
Mitglied: colinardo
21.01.2016, aktualisiert um 10:13 Uhr
Auch kein Hexenwerk
01.
Set objShell = CreateObject("Wscript.Shell") 
02.
Set regex = CreateObject("vbscript.regexp") 
03.
regex.IgnoreCase = True : regex.Global = True 
04.
regex.Pattern = ":((B|E)\d{4}-[^\s]+)" 
05.
'Befehl ausführen 
06.
Set oExec = objShell.Exec("cmd /c zbarimg Test-Datei.jpg") 
07.
 
08.
'Warte darauf das der Befehl beendet wurde 
09.
Do While oExec.Status = 0 
10.
     WScript.Sleep 100 
11.
Loop 
12.
 
13.
' StdOut auslesen 
14.
out = "" 
15.
Do While Not oExec.StdOut.AtEndOfStream 
16.
   out = out & oExec.StdOut.ReadAll 
17.
Loop 
18.
 
19.
Set matches = regex.Execute(out) 
20.
if matches.count > 0 then 
21.
    for each match in matches 
22.
        Msgbox match.submatches(0) 
23.
    next 
24.
end if
-edit- Code etwas angepasst
Bitte warten ..
Mitglied: goodbytes
21.01.2016 um 09:17 Uhr
Hallo,
eine Frage dazu. Könnte ich nicht direkt an der folgenden Stelle den Rückgabestream auf das erste Auftreten von "B20" oder "E20" prüfen und die Schleife mit dem Wert als Varialbe (wie im obigen Beispiel) "B2016-12345" oder "E2016-12345" verlassen?
01.
Do While Not objExec.StdOut.AtEndOfStream 
02.
      out =out & objExec.StdOut.ReadAll 
03.
Loop
Wäre das nicht der schnellere Weg, statt die Ausgabe in "out" nachträglich nach einem String zu durchsuchen? Oder sehe ich da etwas falsch? Wenn es tatsächlich so wäre, wie sähe das dann aus?
Ansonsten müsste ich wohl nachträglich "out" zuerst nach "vbCrlf" splitten...
01.
MyVar = Split(out,"vbCrlf,",-1,1)(0)
...dann das Ergebnis nach ":" splitten...
01.
MyVar = Split(out,":",-1,1)(1)
...um zum Schluss zu überprüfen ob der Rest mit "B20" oder "E20" beginnt.
01.
If UCase(Left(out,3)) = "B20" or UCase(Left(out,3) = "E20") Then ...
Wenn es nicht zutrifft dann weiter. Es kommt mir so aber ziemlich umständlich vor... Was meint ihr dazu?

Gruß
Torsten
Bitte warten ..
Mitglied: goodbytes
21.01.2016 um 09:54 Uhr
Hallo Uwe,
unsere Kommentare haben sich vorhin gerade überschnitten. Danke erstmal für deinen...
Über so einen regulären Ausdruck scheint es ja zu funktionieren. Was bedeuten die Parameter "regex.Pattern = ": (B|E)\d{4}-[^\s]+" im Detail?
Der Teil ": (B|E)" bedeutet ich suche nach dem Vorkommen ":B" oder ":E". Ist natürlich clever hier gleich den Doppelpunkt einzubringen, das erspart mir das zweite splitten. Herausfiltern kann ich den Doppelpunkt ohnehin danach dann mittels:
01.
Replace(strFileNameNew,":","",1,-1,1)
Der String "-[^\s]" sagt dann sicher, dass ab dem Zeilenumbruch neu verglichen werden muss? Und was bedeutet "d{4}" und "+"? Und weshalb ist es nicht möglich auf mehr Zeichen abzuprüfen, statt auf ":B" auf "B20"? Wenn ich es so mache: ": (B20|E20)\d{4}-[^\s]+" wird kein Vorkommen gefunden. Ich möchte nur weitestgehend garantieren, dass ich auch den richtigen String gefunden habe, da machen noch zwei Stellen mehr viel aus.
Sorry, wenn ich deine Zeit dafür so beanspruche, aber ich möchte es natürlich gerne verstehen, was ja auch Sinn des Forums ist... Auf jeden Fall nochmal vielen vielen Dank für deine Hilfe...

Gruß
Torsten
Bitte warten ..
Mitglied: colinardo
LÖSUNG 21.01.2016, aktualisiert um 11:11 Uhr
Zitat von goodbytes:

Hallo Uwe,
unsere Kommentare haben sich vorhin gerade überschnitten. Danke erstmal für deinen...
Über so einen regulären Ausdruck scheint es ja zu funktionieren. Was bedeuten die Parameter "regex.Pattern = ": (B|E)\d{4}-[^\s]+" im Detail?
Der Teil ": (B|E)" bedeutet ich suche nach dem Vorkommen ":B" oder ":E". Ist natürlich clever hier gleich den Doppelpunkt einzubringen, das erspart mir das zweite splitten.
Korrekt, Suche nach einem Doppelpunkt gefolgt von einem E oder B
Herausfiltern kann ich den Doppelpunkt ohnehin danach dann mittels:
Das korrigiere ich oben noch mit einer Klammersetzung im Regex, hätte ich vergessen, dann ist das ausfiltern des Doppelpunktes nicht mehr nötig.
Der String "-[^\s]" sagt dann sicher, dass ab dem Zeilenumbruch neu verglichen werden muss?
Nein, das bedeutet suche nach Bindestrich gefolgt von mindestens einem Zeichen was kein unsichtbares Zeichen (Leerzeichen/Zeilenumbruch/etc.) ist, damit diese nicht im String landen.
Und was bedeutet "d{4}" und "+"?
\d{4} bedeutet suche genau nach einer Zahl und das genau 4 mal, das + ist ein Quantifizierungsoperator und sagt matche das vorherige Muster mindestens einmal, hier also "mindestens" ein Zeichen was kein unsichtbares Zeichen ist.

Und weshalb ist es nicht möglich auf mehr Zeichen abzuprüfen, statt auf ":B" auf "B20"? Wenn ich es so mache: ": (B20|E20)\d{4}-[^\s]+" wird kein Vorkommen gefunden. Ich möchte nur weitestgehend garantieren, dass ich auch den richtigen String gefunden habe, da machen noch zwei Stellen mehr viel aus.
Das ist durch meine obigen Kommentare nun erledigt...
Sorry, wenn ich deine Zeit dafür so beanspruche, aber ich möchte es natürlich gerne verstehen, was ja auch Sinn des Forums ist... Auf jeden Fall nochmal vielen vielen Dank für deine Hilfe...

Kein Problem.
Aber einmal kurz in die Regular Expression Syntax Referenz geschaut hätte dir bestimmt auch geholfen den Pattern zu verstehen

Grüße Uwe
Bitte warten ..
Mitglied: goodbytes
21.01.2016 um 11:21 Uhr
Ich hab nun nochmal in die Regular Expression Syntax Referenz geschaut, da ich noch meine Probleme mit dem "\d{4}" hatte...
Jetzt ist es natürlich klar, wenn ich z.B. nach "B2016-..." suche nehme ich entweder ": ((B20|E20)\d{2}-[^\s]+)", dann prüfe ich genau auf "B20" bzw. "E20" und zwei beliebigen Zahlen und "-" ab, dagegen bei ": ((B2016|E2016)-[^\s]+)" muss die Jahreszahl komplett sein, gefolgt von einem "-".
Super, es funktioniert bestens jetzt, Danke Uwe !!!

Gruß
Torsten
Bitte warten ..
Mitglied: colinardo
21.01.2016, aktualisiert um 12:19 Uhr
OK schön das du es verstanden hast, wusste halt nicht wie deine Daten aussehen "könnten", aber du hast es ja schon richtig an deine Bedürfnisse angepasst, solange das Skript nicht im nächsten Jahrhundert laufen muss (ob's dann noch VBS gibt ? vielleicht im Museum )
Bitte warten ..
Mitglied: goodbytes
22.01.2016 um 09:39 Uhr
Nun muss ich also nur noch aufpassen, dass ich am Silvesterabend am 31.12.2099 nicht noch hektisch an meinen Rechner rennen muss weil ich vergessen hab das Script auf das neue Jahrhundert umzustellen... *lach*
Bitte warten ..
Mitglied: colinardo
22.01.2016, aktualisiert um 10:14 Uhr
Nun muss ich also nur noch aufpassen, dass ich am Silvesterabend am 31.12.2099 nicht noch hektisch an meinen Rechner rennen muss weil ich vergessen hab das Script auf das neue Jahrhundert umzustellen... *lach*
Wenn, ja wenn dir die nette Pflegedame nicht die Feststellbremse an deinem Rollstuhl eingerastet hätte...
Bitte warten ..
Mitglied: goodbytes
22.01.2016 um 10:29 Uhr
Hahaha, ja genau... *lach*
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(4)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst Batch Problem bei einer For Schleife (2)

Frage von Juergen42 zum Thema Batch & Shell ...

Batch & Shell
Batch: Variable Expansion in einer FOR-Schleife (9)

Frage von .Sessl zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Probleme mit Dateipfaden in for-Schleife (1)

Frage von Jonas1806 zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Schleife als FOR-SCHLEIFE (2)

Frage von mp2711 zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...

Outlook & Mail
Outlook 2010 findet ost datei nicht (18)

Frage von Floh21 zum Thema Outlook & Mail ...

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

Frage von Unwichtig zum Thema Netzwerkmanagement ...