andynix
Goto Top

for /f "tokens=6,7 delims= " in VBS

Hallo,
Wie kann ich eine Log-Datei auslesen und überprüfen wie in diesen Batchschnipsel mit WSH ?
...
:AUSWERTUNG
for /f "tokens=6,7 delims= " %%i in ('type F:\log.txt^|find "Dirs"') do set /a "cntMismatch+=%%i, cntFailed+=%%j"  
if not %cntMismatch%==0 goto FEHLER
if not %cntFailed%==0 goto FEHLER
...

Content-Key: 47505

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

Printed on: April 25, 2024 at 11:04 o'clock

Member: bastla
bastla Dec 28, 2006 at 16:42:35 (UTC)
Goto Top
Hallo Andynix!

Vorweg: Obwohl ich persönlich recht gerne VBScript verwende, würde ich gerade für diese Aufgabenstellung nicht unbedingt dazu raten.

Ausgehend von der Annahme, dass es sich bei "log.txt" um die Ausgabe von "Robocopy" handelt, könnte das so aussehen:
'CheckRobocopyLog.vbs  
Const sLogFile = "F:\log.txt"  
Const sMarker = "     Dirs :" 'Kennzeichen am Zeilenanfang  
Const sOK = "Sicherung erfolgreich."  
sMarkLen = Len(sMarker)
Set fso = WScript.CreateObject("Scripting.FileSystemObject")  
Set oLogFile = fso.OpenTextFile(sLogFile, 1)
Do While Not oLogFile.AtEndOfStream
	sLine = oLogFile.ReadLine
	If Left(sLine, sMarkLen) = sMarker Then
		sValues = Trim(Mid(sLine, sMarkLen + 1)) 'hinter Kennzeichen befinden sich die Werte  
		Exit Do 'weitere Zeilen nicht mehr untersuchen  
	End If
Loop
oLogFile.Close

'Auswertung  
If sValues <> "" Then  
	sMsg = sOK
	iPos = Instr(sValues, " ")  
	If iPos > 1 Then
		iTotal = CInt(Left(sValues, iPos - 1))
	End If
	sValues = Trim(Mid(sValues, iPos))
	iPos = Instr(sValues, " ")  
	If iPos > 1 Then
		iCopied = CInt(Left(sValues, iPos - 1))
	End If
	sValues = Trim(Mid(sValues, iPos))
	iPos = Instr(sValues, " ")  
	If iPos > 1 Then
		iSkipped = CInt(Left(sValues, iPos - 1))
	End If
	sValues = Trim(Mid(sValues, iPos))
	iPos = Instr(sValues, " ")  
	If iPos > 1 Then
		iMismatch = CInt(Left(sValues, iPos - 1))
	End If
	sValues = Trim(Mid(sValues, iPos))
	iPos = Instr(sValues, " ")  
	If iPos > 1 Then
		iFailed = CInt(Left(sValues, iPos - 1))
	End If
	sValues = Trim(Mid(sValues, iPos))
	iExtras = CInt(sValues)

	'Aufbereitung Ergebnis  
	If iMismatch <> 0 Then
		sMsg = "Mismatches:"  & vbTab & iMismatch  
	End If
	If iFailed <> 0 Then
		If sMsg <> sOK Then
			sMsg = sMsg & vbCrLF & "FAILED: " & vbTab & vbTab & iFailed  
		Else
			sMsg = "FAILED: " & vbTab & iFailed  
		End If
	End If
Else
	sMsg = "Dirs-Daten nicht gefunden!"  
End If

WScript.Echo sMsg
If sMsg <> sOK Then WScript.Quit(1) 'Errorlevel setzen  
Anmerkung: Es wird nicht überprüft, ob die Log-Datei überhaupt existiert, der Auswertungsteil ließe sich natürlich eleganter schreiben und was die Aufbereitung / Ausgabe / Weiterverwendung des Ergebnisses anlangt, musst Du ohnehin Deine Vorstellungen umsetzen - solltest Du das wirklich per VBS lösen wollen ...

Grüße
bastla
Member: Andynix
Andynix Dec 29, 2006 at 00:33:32 (UTC)
Goto Top
Erstens:
Danke es fuktioniert ! Ist halt nur heftig im Vergleich zur 3 Batchzeilen !

Zweitens:
Wieso kann ich nicht einfach den sMarker ändern um Files auszulesen z.B. so Const sMarker = " Files :"
(...ja mit einen Leerschritt weniger als bei Dirs:)
Member: bastla
bastla Dec 29, 2006 at 08:01:43 (UTC)
Goto Top
Hallo Andynix!

Zu Erstens: "Heftig" ist eigentlich noch untertrieben ...

Zu Zweitens: "Files :" eignet sich nicht als Kennzeichen, da es mehr als einmal im Log am Anfang einer Zeile steht - Du müsstest also den String eindeutig machen (zB " Files : ", also noch mindestens 2 Leerzeichen nach dem ":").

Grüße
bastla
Member: Andynix
Andynix Dec 31, 2006 at 14:21:46 (UTC)
Goto Top
Vielen Dank, es funktioniert mit "Files: " und 2 Leerschritten wunderbar.
Ich habe es gleich für meine private Backup-Batch-Datei verwendet.
("Eigene Dateien" auf eine externe HDD sichern)

dim objNet,wshell,fso

set objNet = CreateObject("WScript.NetWork")  
set wshell = CreateObject("Wscript.shell")  
set fso = CreateObject("Scripting.FileSystemObject")  

frage=msgbox("Backup vom USB-Stick auf der Festplatte erstellen ?",vbyesno + vbQuestion ,"Frage")'  
if frage=vbNo then WScript.quit'  

if not objNet.ComputerName = "PC-ANDREAS" Then  
MsgBox "Falscher Computer, kein Backup",vbExclamation  
elseif not fso.FolderExists("F:\PC-ANDREAS\_new") then  
MsgBox "F:\PC-ANDREAS\ nicht da, also kein Backup",vbExclamation  
wscript.quit
else call pc_andreas
end if

sub pc_andreas
Set f1 = fso.Getfolder("F:\PC-ANDREAS\_new")  
f1.move ("F:\PC-ANDREAS\_old1")  
Set f2 = fso.Getfolder("F:\PC-ANDREAS\_old")  
f2.move ("F:\PC-ANDREAS\_new")  
Set f3 = fso.Getfolder("F:\PC-ANDREAS\_old1")  
f3.move ("F:\PC-ANDREAS\_old")  

wshell.popup "USB Backup wird gerade erstellt...",9,"Meldung verschwindet automatisch"  

wshell.run "robocopy.exe ""E:\Eigene Dateien"" ""F:\PC-ANDREAS\_new\Eigene Dateien"" /MIR /NFL /NDL /R:3 /LOG:F:\PC-ANDREAS\_new.txt",0,true  
wshell.run "robocopy.exe ""E:\Eigene Bilder"" ""F:\PC-ANDREAS\_new\Eigene Bilder"" /MIR /NFL /NDL /R:3 /LOG+:F:\PC-ANDREAS\_new.txt",0,true  

wshell.popup "Der wichtiger Teil ist fertig...",9,"Meldung verschwindet automatisch"  

wshell.run "robocopy.exe ""D:\Eigene Music"" ""F:\PC-ANDREAS\_to_big\Eigene Music"" /MIR /NFL /NDL /R:3 /LOG+:F:\PC-ANDREAS\_new.txt",0,true  
wshell.run "robocopy.exe ""D:\Eigene Videos"" ""F:\PC-ANDREAS\_to_big\Eigene Videos"" /MIR /NFL /NDL /R:3 /LOG+:F:\PC-ANDREAS\_new.txt",0,true  
wshell.run "robocopy.exe ""D:\_Driver_"" ""F:\PC-ANDREAS\_to_big\_Driver_"" /MIR /NFL /NDL /R:3 /LOG+:F:\PC-ANDREAS\_new.txt",0,true  
wshell.run "robocopy.exe ""D:\PQDI"" ""F:\PC-ANDREAS\_to_big\PQDI"" /MIR /NFL /NDL /R:3 /LOG+:F:\PC-ANDREAS\_new.txt",0,true  

call CheckRobocopyLog
end sub
wscript.quit

Wobei call CheckRobocopyLog das Schnipsel von oben von bastla aufruft das sich unter wscript.quit befindet.
(wegen der Länge habe ich hier gespart)

Ich glaube nicht das es besonders schön ist (ist der call Aufruf überhaupt ok?) aber es funktioniert für mich persönlich sehr gut.

Zu Erklärung
- es befindet sich auf der USB HDD (Fface-smile
-- ein Ordner namens PC-ANDREAS
--- mit 2 Unterordnern _new und _old
Wegen der großen Datenmenge werden vor dem Backup die Ordner umbenannt und erst dann neu synchronisiert.
(so dass immer das "letzte" und "vorletzte" Backup zur Verfügung steht, kann man das verstehen ?)
es gibt auch einen _to_big der einfach mit der Festplatte synchronisiert wird

PS.: es kommt noch eine Datumsabfrage, welche davor warnt wenn das Backup erst heute erstellt wurde.