alfabravo
Goto Top

Textdatei .txt mit .vbs auf doppelte Werte prüfen und ggf. zerlegen

Hallo Admins,

ich möchte möglichst mit vbs eine Datei namens 'Quelle.txt' zerlegen:

Sobald eine Kundennummer (8stellig, hier an Stelle 18-25) ein weiteres mal in einer Zeile vorkommt, soll die betreffende Zeile in eine neue Datei geschrieben werden und aus der Quelle.txt gelöscht werden.

Beispiel:

Vorher:

Quelle.txt:

Dies ist Zeile 1 44001234 Dies ist Zeile 1
Dies ist Zeile 2 45209999 Dies ist Zeile 2
Dies ist Zeile 3 44001234 Dies ist Zeile 3


Nach der Verarbeitung:

Ziel1.txt:

Dies ist Zeile 1 44001234 Dies ist Zeile 1
Dies ist Zeile 2 45209999 Dies ist Zeile 2


Ziel2.txt:

Dies ist Zeile 3 44001234 Dies ist Zeile 3


Da auch Sonderzeichen vorkommen können (z.B.: &) sollte es über ein *.vbs Skript laufen (und nicht über Batch).

Hat jemand eine Lösung dafür?

Vielen Dank!

Content-Key: 216109

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

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

Member: colinardo
colinardo Sep 04, 2013 updated at 15:16:54 (UTC)
Goto Top
Halo alfabravo,
das könntest du hiermit machen:
(In den Zeilen 1-3 noch die Pfade anpassen)
strQuellPfad ~ Quelle.txt
strZielClean ~ Ziel1.txt
strZielDupes ~ Ziel2.txt
Const strQuellPfad = "E:\Scripte\quelle.txt"  
Const strZielClean = "E:\Scripte\ziel1.txt"  
Const strZielDupes = "E:\Scripte\ziel2.txt"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objQuelleRead = fso.OpenTextFile(strQuellPfad,1)
arrContent = Split(objQuelleRead.ReadAll(),vbNewLine)
objQuelleRead.Close

Set regex = New RegExp
Set objDupes = fso.OpenTextFile(strZielDupes,2,True)
For i = 0 To UBound(arrContent)
	regex.Pattern = "\s\d{8}\s"  
	Set matches = regex.Execute(arrContent(i))
	If matches.Count > 0 Then
		strKDNR = matches(0)
		regex.Pattern = strKDNR
		For x = (i+1) To UBound(arrContent)
			If regex.Test(arrContent(x)) Then
				objDupes.WriteLine(arrContent(x))
				arrContent(x) = ""  
			End If
		Next
	End If
Next
objDupes.Close

Set objZiel = fso.OpenTextFile(strZielClean,2,True)
For z = 0 To UBound(arrContent)
	If arrContent(z) <> "" Then  
		objZiel.WriteLine(arrContent(z))
	End If
Next
objZiel.Close
Set fso = Nothing
MsgBox "Fertig!"  
Wenn du keine zusätzliche Datei (ziel1.txt) mit den bereinigten Zeilen möchtest sondern das ganze in die Quelle zurückschreiben möchtest ist das auch kein Problem. Einfach in die Variable strZielClean den selben Pfad eintragen wie bei strQuellPfad.

Grüße Uwe
Member: alfabravo
alfabravo Sep 04, 2013 at 15:43:13 (UTC)
Goto Top
Hallo Uwe,

ich danke Dir vielmals, das klappt schon ganz hervorragend. Wenn ich das richtig sehe, sind die Leerzeichen vor und nach der Kundennummer von Bedeutung, um die Kundennummer zu 'extrahieren'. Ginge das Ganze auch, wenn vor und nach der Kundennummer keine Leerzeichen, sondern beliebige andere Zeichen stehen? Also wenn die Quelle z. B. so aussieht:

DiesistZeile1abcd44001234abcdDiesistZeile1DiesistZeile2abc 44209999abcdDiesistZeile2DiesistZeile3abcd44001234 bcdDiesistZeile3

Zwei Dinge sind jedenfalls in jeder Zeile immer gleich:
1.) die Kundennummer ist 8stellig
2.) und steht an Position 18 bis 25

Gruß, alfabravo
Member: colinardo
colinardo Sep 04, 2013 at 16:39:33 (UTC)
Goto Top
kein Problem. Ändere Zeile 13 so ab:
regex.Pattern = "\d{8}"   
Member: Biber
Biber Sep 04, 2013 updated at 18:13:51 (UTC)
Goto Top
Moin colinardo,

das kann klappen, muss aber nicht.

Wenn durch Zufall oder Zwang in diesem FixedLen-Flatfile
  • unmittelbar vor oder nach der Kundennummer Ziffern stehen
  • an anderer Stelle in der Zeile auch mal 8 oder mehr Ziffern stehen könnten

-> dann wird es wacklig.
Beispiel:
DiesistZeile1abcd44001234abcdDiesistZeile1
DiesistZeile2abc 44209999abcdDiesistZeile2
DiesistZeile3abcd44001234 bcdDiesistZeile3
DiesistZeile5abc7550012341bcdDiesistZeile5
DiesistZeile4abcx55001234 bcdDiesistZeile4

Mit dieser Test-Datei kommen je nach Reihenfolge der Zeile unterschiedliche Ergebnisse.
Wenn "Zeile4" vor "Zeile5" steht-> korrektes Ergebnis im Sinne der TO.
Wenn "Zeile5" vor "Zeile4" steht-> Duplikat im Sinne TO wird nicht erkannt.

Ich denke, du musst wohl oder übel mit Substring/festen Offsets arbeiten (=Mid(arrContent[i], 18, 8) ).

Grüße
Biber
Member: colinardo
colinardo Sep 04, 2013 updated at 19:17:02 (UTC)
Goto Top
@Biber
schon kloar, mach ich ungern aber wenn's denn sein muss 8-)

Const strQuellPfad = "E:\Scripte\quelle.txt"  
Const strZielClean = "E:\Scripte\ziel1.txt"  
Const strZielDupes = "E:\Scripte\ziel2.txt"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objQuelleRead = fso.OpenTextFile(strQuellPfad,1)
arrContent = Split(objQuelleRead.ReadAll(),vbNewLine)
objQuelleRead.Close

Set regex = New RegExp
Set objDupes = fso.OpenTextFile(strZielDupes,2,True)
For i = 0 To UBound(arrContent)
	regex.Pattern = "^\d{8}"  
	Set matches = regex.Execute(Mid(arrContent(i),18))
	If matches.Count > 0 Then
		strKDNR = matches(0)
		regex.Pattern = strKDNR
		For x = (i+1) To UBound(arrContent)
			If regex.Test(Mid(arrContent(x),18)) Then
				objDupes.WriteLine(arrContent(x))
				arrContent(x) = ""  
			End If
		Next
	End If
Next
objDupes.Close

Set objZiel = fso.OpenTextFile(strZielClean,2,True)
For z = 0 To UBound(arrContent)
	If arrContent(z) <> "" Then  
		objZiel.WriteLine(arrContent(z))
	End If
Next
objZiel.Close
Set fso = Nothing
MsgBox "Fertig!"  
Member: alfabravo
alfabravo Sep 04, 2013 at 18:20:16 (UTC)
Goto Top
@colinardo (Uwe)
Klasse Skript. Funktioniert jetzt perfekt. Vielen Dank!

@Biber
Danke für Deine Anmerkung. Das war das i-Tüpfelchen.

Gruß, alfabravo