Script zum vergleich von Dateien
Hallo,
das folgende Script soll Objfile1 sequentiell auslesen und jeden Eintrag in ObjFile2 suchen.
Im Moment läuft das Script nur einmal durch das heißt die Function main() wird nur mit einem, dem ersten, Suchbegriff durchlaufen
das Script scheint nicht zurück zu kommen um sich den zweiten Suchbegriff zu holen. Warum, wie kann ich das korrigieren oder besser machen?
Gruss
Andreas
das folgende Script soll Objfile1 sequentiell auslesen und jeden Eintrag in ObjFile2 suchen.
Im Moment läuft das Script nur einmal durch das heißt die Function main() wird nur mit einem, dem ersten, Suchbegriff durchlaufen
das Script scheint nicht zurück zu kommen um sich den zweiten Suchbegriff zu holen. Warum, wie kann ich das korrigieren oder besser machen?
Gruss
Andreas
dim zeile,Suchbegriff,FileSystem,OutPutFile,OUtPutFile2
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile1 = objFSO.OpenTextFile("C:\Temp\Dis-User-in-delOU.csv",1)
Set objFile2 = objFSO.OpenTextFile("C:\Temp\ts-Verzeichnisse-die-fehlen.csv",1)
i = 0
u = 0
Do Until objFile1.AtEndOfStream
Suchbegriff = objFile1.ReadLine
call main()
loop
Function main()
Do Until objFile2.AtEndOfStream
Zeile = objFile2.ReadLine
If InStr(1,Zeile,Suchbegriff,1) Then
i = i + 1
else
u = u + 1
end if
Loop
end function
call msgbox ("Suchbegriff " & Suchbegriff & " " & i & "x gefunden",16,"Abschlussmeldung")
call msgbox ("Suchbegriff " & Suchbegriff & " " & u & "x nicht gefunden",16,"Abschlussmeldung")
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Kommentar vom Moderator Biber am 13.08.2009 um 22:53:34 Uhr
Tippfehler im Originaltitel "Scipt zum vergleich von Dateien" berichtigt.
Content-ID: 122570
Url: https://administrator.de/forum/script-zum-vergleich-von-dateien-122570.html
Ausgedruckt am: 23.12.2024 um 10:12 Uhr
20 Kommentare
Neuester Kommentar
Hallo JoshuaTree!
Wenn Du für jede Zeile in objFile1 eine Ausgabe erhalten willst, musst Du diese Ausgabe natürlich innerhalb der Schleife vornehmen (und auch die Zähler jeweils innerhalb der Schleife zurücksetzen)
Alternative zu Deinem Ansatz: Erspare Dir die (an dieser Stelle ohnehin suboptimal platzierte "Function" - die, von der Verwendung her, außerdem eigentlich ein "Sub" wäre) und packe alles in die erste Schleife - dazu müsstest Du nur die Zeilen 15 bis 18 sowie 31 entfernen und am Ende eine Zeile "Loop" ergänzen (und, wie vorher schon angesprochen, die Zeilen 7 und 8 innerhalb der Schleife verwenden).
Abgesehen davon ist die Vorgangsweise ziemlich ineffektiv. Wenn Du schon nicht eine Suche mit "regulären Ausdrücken" durchführen willst, wäre es aber sinnvoll, zunächst die beiden Dateien in Arrays (und damit in den Arbeitsspeicher) einzulesen und damit nur einmal auf die Dateien zugreifen zu müssen - das sähe etwa so aus:
Anmerkungen:
Wenn Du anstelle von "MsgBox" ein "WScript.Echo" verwendest, kannst Du wesentlich bequemer (nämlich an der Kommandozeile mit zB "cscript //nologo D:\DeinScript.vbs") testen, da Du dann nicht jede Ausgabe einzeln bestätigen musst. Wird das Script über "wscript" (also zB per Doppelklick) gestartet, erhältst Du für jedes "WScript.Echo" wieder eine MsgBox ...
Die Variablendeklarationen habe ich eingespart, da diese mE nur dann sinnvoll sind, wenn auch konsequent alle Variablen deklariert werden und dies per "Option Explicit" auch kontrolliert wird - in einem kurzen und übersichtlichen Script kannst Du aber auch ohne Deklarationen zurechtkommenn.
Grüße
bastla
P.S.: Vielleicht fällt Dir auch noch ein etwas aussagekräftigerer Titel für den Thread ein ...
Wenn Du für jede Zeile in objFile1 eine Ausgabe erhalten willst, musst Du diese Ausgabe natürlich innerhalb der Schleife vornehmen (und auch die Zähler jeweils innerhalb der Schleife zurücksetzen)
Alternative zu Deinem Ansatz: Erspare Dir die (an dieser Stelle ohnehin suboptimal platzierte "Function" - die, von der Verwendung her, außerdem eigentlich ein "Sub" wäre) und packe alles in die erste Schleife - dazu müsstest Du nur die Zeilen 15 bis 18 sowie 31 entfernen und am Ende eine Zeile "Loop" ergänzen (und, wie vorher schon angesprochen, die Zeilen 7 und 8 innerhalb der Schleife verwenden).
Abgesehen davon ist die Vorgangsweise ziemlich ineffektiv. Wenn Du schon nicht eine Suche mit "regulären Ausdrücken" durchführen willst, wäre es aber sinnvoll, zunächst die beiden Dateien in Arrays (und damit in den Arbeitsspeicher) einzulesen und damit nur einmal auf die Dateien zugreifen zu müssen - das sähe etwa so aus:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Text1 = Split(objFSO.OpenTextFile("C:\Temp\Dis-User-in-delOU.csv").ReadAll, vbCrLF)
Text2 = Split(objFSO.OpenTextFile("C:\Temp\ts-Verzeichnisse-die-fehlen.csv").ReadAll, vbCrLF)
For Each Suchbegriff In Text1
i = 0
u = 0
For Each Zeile In Text2
If InStr(1, Zeile, Suchbegriff, 1) Then
i = i + 1
Else
u = u + 1
End If
Next
'Call MsgBox("Suchbegriff " & Suchbegriff & " " & i & "x gefunden", 16, "Abschlussmeldung")
'Call MsgBox("Suchbegriff " & Suchbegriff & " " & u & "x nicht gefunden", 16, "Abschlussmeldung")
WScript.Echo "Suchbegriff " & Suchbegriff & " " & i & "x gefunden"
WScript.Echo "Suchbegriff " & Suchbegriff & " " & u & "x nicht gefunden" & vbCrLF
Next
Wenn Du anstelle von "MsgBox" ein "WScript.Echo" verwendest, kannst Du wesentlich bequemer (nämlich an der Kommandozeile mit zB "cscript //nologo D:\DeinScript.vbs") testen, da Du dann nicht jede Ausgabe einzeln bestätigen musst. Wird das Script über "wscript" (also zB per Doppelklick) gestartet, erhältst Du für jedes "WScript.Echo" wieder eine MsgBox ...
Die Variablendeklarationen habe ich eingespart, da diese mE nur dann sinnvoll sind, wenn auch konsequent alle Variablen deklariert werden und dies per "Option Explicit" auch kontrolliert wird - in einem kurzen und übersichtlichen Script kannst Du aber auch ohne Deklarationen zurechtkommenn.
Grüße
bastla
P.S.: Vielleicht fällt Dir auch noch ein etwas aussagekräftigerer Titel für den Thread ein ...
Hallo Andreas!
Wie gewünscht noch eine kurze Erklärung zum Script:
Durch die Verwendung von "Split()" mit dem Trennzeichen "vbCrLF" (= Windows-Zeilenschaltung) entsteht ein eindimensionales Array, welches in jedem Element eine Zeile (bei einer Leerzeile einen Leerstring) der eingelesenen Textdatei enthält.
Die "For-Each"-Schleife ermöglicht das Abarbeiten aller Array-Elemente, wobei das jeweilige Element in der Schleifenvariable (zB "Suchbegriff") zur Verfügung gestellt wird - Alternative dazu:
Diese Schreibweise ist dann sinnvoll, wenn der Index benötigt wird, um etwa nur eine bestimmte Anzahl von Elementen zu verarbeiten - für die letzten 20 Zeilen hieße es dann etwa
In solchen Situationen bringt das Einlesen des Textfiles in das Array nicht nur einen Geschwindigkeitsvorteil, sondern vereinfacht auch die Verarbeitung (da Du dann schon weißt, wieviele Zeilen es insgesamt gibt).
Grüße
bastla
Wie gewünscht noch eine kurze Erklärung zum Script:
Durch die Verwendung von "Split()" mit dem Trennzeichen "vbCrLF" (= Windows-Zeilenschaltung) entsteht ein eindimensionales Array, welches in jedem Element eine Zeile (bei einer Leerzeile einen Leerstring) der eingelesenen Textdatei enthält.
Die "For-Each"-Schleife ermöglicht das Abarbeiten aller Array-Elemente, wobei das jeweilige Element in der Schleifenvariable (zB "Suchbegriff") zur Verfügung gestellt wird - Alternative dazu:
For i = 0 To UBound(Text1)
Suchbegriff = Text1(i)
...
Next
Ab = UBound(Text1) - 19
If Ab < 0 Then Ab = 0
For i = Ab To UBound(Text1)
...
Grüße
bastla
Hallo Andreas!
"UBound()" liefert den höchsten Index des Arrays, und da Arrays in VBS null-basiert sind, gibt es ein Element (Test1(0)) mehr ...
ausgeben, oder Du musst das gesamte Array wieder zu einem einzigen String zusammenfügen - das sähe so aus:
Wie das Zusammenfügen erfolgt, kannst Du an diesem Beispiel sehen:
WScript.Echo Join(Text1, "[Zeilenende]" & vbCrLF & "[Zeilenanfang]")
Mit einer Schleife kannst Du natürlich auch alle einzelnen Elemente anzeigen lassen:
Grüße
bastla
Und kann man sich die Anzahl der Zeilen auch schon vorher ausgeben lassen wenn man sie schon weiß?
Die Zeilenanzahl istUBound(Text1) + 1
"UBound()" liefert den höchsten Index des Arrays, und da Arrays in VBS null-basiert sind, gibt es ein Element (Test1(0)) mehr ...
ich wollte mir nun gerade mal die Variable bzw. das Array Text1 mit wscript.echo ausgeben lassen das ging nicht. Warum ?
Da das Array aus mehreren Elementen besteht, kannst Du entweder ein bestimmtes Element, zB die vierte Zeile mitWScript.Echo Text1(3)
WScript.Echo Join(Text1, vbCrLF)
WScript.Echo Join(Text1, "[Zeilenende]" & vbCrLF & "[Zeilenanfang]")
Mit einer Schleife kannst Du natürlich auch alle einzelnen Elemente anzeigen lassen:
For i = 0 To UBound(Text1)
WScript.Echo i, Text1(i)
Next
bastla
Hallo Andreas!
Soferne es Dir nur darum geht, alle Zeilen aus Text1, die überhaupt nicht in Text2 enthalten sind, in die "vergleich.csv" zu schreiben, solltest Du Text2 am Stück belassen und es etwa so realisieren:
Es genügt übrigens ein "FileSystemObject" pro Script ...
Grüße
bastla
Soferne es Dir nur darum geht, alle Zeilen aus Text1, die überhaupt nicht in Text2 enthalten sind, in die "vergleich.csv" zu schreiben, solltest Du Text2 am Stück belassen und es etwa so realisieren:
Datei = "vergleich.csv"
PFad = "c:\temp\"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Text1 = Split(objFSO.OpenTextFile("C:\Temp\Dis-User-in-delOU.csv").ReadAll, vbCrLF)
Text2 = objFSO.OpenTextFile("C:\Temp\ts-Verzeichnisse-die-fehlen.csv").ReadAll
Set OutPutFile = objFSO.CreateTextFile(Pfad & Datei, True)
OutPutFile.WriteLine "Name;Verzeichnis"
For Each Suchbegriff In Text1
If InStr(1, Text2, Suchbegriff, vbTextCompare) = 0 Then outputFile.WriteLine Suchbegriff
Next
wscript.echo "fäddisch"
Grüße
bastla
Hallo Andreas!
Da mir der Inhalt der beiden Dateien nicht bekannt ist, zwei Vorschläge:
Grüße
bastla
Da mir der Inhalt der beiden Dateien nicht bekannt ist, zwei Vorschläge:
- Versuche es mit einem Vertauschen von "Text1" und "Text2" in den Zeilen 6 und 7, und falls das nicht das gewünschte Ergebnis liefert,
- poste bitte auszugsweise (und anonymisiert) einige Zeilen aus beiden Dateien und das gewünschte Ergebnis ...
Grüße
bastla
Hallo Andreas!
Mal dauert's lang, dann wieder länger (bis der Groschen fällt) ...
Nur als Randbemerkung: In Batch (bzw direkt von der Kommandozeile) würde sich das Ganze (mit der Einschränkung, dass nur die Pfade ausgegeben werden) reduzieren auf:
bzw ohne die genannte Einschränkung, aber mit Laufzeitnachteilen auf:
Grüße
bastla
Mal dauert's lang, dann wieder länger (bis der Groschen fällt) ...
Datei = "vergleich.csv"
PFad = "C:\temp\"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Text1 = Split(objFSO.OpenTextFile("C:\Temp\Dis-User-in-delOU.csv").ReadAll, vbCrLf)
Text2 = Split(objFSO.OpenTextFile("C:\Temp\ts-Verzeichnisse-die-fehlen.csv").ReadAll, vbCrLf)
Set OutPutFile = objFSO.CreateTextFile(Pfad & Datei, True)
OutPutFile.WriteLine "Name;Verzeichnis"
For Each Pfad In Text2
Username = Mid(Pfad, InStrRev(Pfad, "\") + 1)
Anlegen = True
For Each User In Text1
If StrComp(User, Username, vbTextCompare) = 0 Then
Anlegen = False
Exit For
End If
Next
If Anlegen Then outputFile.WriteLine Username & ";" & Pfad
Next
WScript.Echo "fäddisch"
Nur als Randbemerkung: In Batch (bzw direkt von der Kommandozeile) würde sich das Ganze (mit der Einschränkung, dass nur die Pfade ausgegeben werden) reduzieren auf:
findstr /v /i /e /g:"C:\TEMP\Dis-User-in-delOU.csv" "C:\temp\ts-Verzeichnisse-die-fehlen.csv">"C:\temp\vergleich.csv"
for /f "delims=" %i in ('findstr /v /i /e /g:"C:\TEMP\Dis-User-in-delOU.csv" "C:\temp\ts-Verzeichnisse-die-fehlen.csv"') do @>>"C:\temp\vergleich.csv" echo %~nxi;%i
bastla
Hallo Andreas!
Was Du offensichtlich wolltest, ist:
Deine "Zeilen" waren bereits die einzelnen Werte, daher auch die 13 Ausgaben von "OU=xxx"(= 4. Wert aus Zeile 1) ...
Und zum Thema "PopUp": Teste von der Kommandozeile mit
Grüße
bastla
Was Du offensichtlich wolltest, ist:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Zeilen = Split(objFSO.OpenTextFile("C:\Temp\cn.txt").ReadAll, vbCrLF) 'Zerlege in Zeilen
For Each Zeile in Zeilen
Werte = Split(Zeile, ",") 'Zerlege in Werte
WScript.Echo Werte(3)
Next
Und zum Thema "PopUp": Teste von der Kommandozeile mit
cscript //nologo D:\DeinScript.vbs
bastla