Anfängerfrage zu Script-Konstruktion
Ich bin ziemlich unerfahren im Scripten und habe folgendes Problem, von dem ich glaube, dass es sich verhälnismäßig einfach per Script automatisieren lassen müßte:
Unter Windows XP SP3 habe ich in einem Verzeichnis eine Reihe von Text-Dateien (33204108.mp, 33204109.mp, 33204208.mp, 33204209.mp, ...).
Der Dateiinhalt besteht im wesentlichen aus einer Vielzahl von sich wiederholenden Einträgen in Form von:
Der Inhalt [POLYLINE] bis [END] ist jeweils variabel enhält aber zumindest immer eine Zeile, welche mit Data0= beginnt und danach eine Vielzahl von kommagetrennten Koordinatenangaben in runden Klammern enthält.
Allerdings gibt es eine Reihe von Fehlern, die darin bestehen, dass zwischen den Tags [POLYLINE] bis [END] der Ausdruck Data0= ab und an mehr als einmal vorhanden ist. Einige Beispielzeilen füge ich unten an:
Ich würde gerne per Script in jeder Textdatei nach allen diesen doppelten Einträgen suchen lassen und mir jeweils , wenn vorhanden, die Zeilennummer des doppelten Eintrags in eine log-Datei analog zum Dateinamen (33204108.log, 33204109.log, ...) schreiben lassen.
Kann mir jemand helfen?
Vielen Dank für alle Vorschläge!
Unter Windows XP SP3 habe ich in einem Verzeichnis eine Reihe von Text-Dateien (33204108.mp, 33204109.mp, 33204208.mp, 33204209.mp, ...).
Der Dateiinhalt besteht im wesentlichen aus einer Vielzahl von sich wiederholenden Einträgen in Form von:
; Kommentar
[POLYLINE]
...
[END]
; Kommentar
[POLYLINE]
...
[END]
Der Inhalt [POLYLINE] bis [END] ist jeweils variabel enhält aber zumindest immer eine Zeile, welche mit Data0= beginnt und danach eine Vielzahl von kommagetrennten Koordinatenangaben in runden Klammern enthält.
Allerdings gibt es eine Reihe von Fehlern, die darin bestehen, dass zwischen den Tags [POLYLINE] bis [END] der Ausdruck Data0= ab und an mehr als einmal vorhanden ist. Einige Beispielzeilen füge ich unten an:
; WayID = 30799184:0
; highway=tertiary
[POLYLINE]
Type=0x5
Label=D86
EndLevel=2
CityIdx=1
RoadID=2870
RouteParam=3,1,0,0,0,0,0,0,0,0,0,0
Data0=(42.55619,8.97413),(42.55608,8.97386), [...] ,(42.55050,8.99999)
Nod1=0,1238,0
Nod2=110,4713,1
Data0=(42.54548,8.99999),(42.54539,8.99993), [...] ,(42.54001,8.99999)
Nodes1=(0,4714,1),(49,1264),(81,1267),(86,1270),(108,4715,1)
[END]
Ich würde gerne per Script in jeder Textdatei nach allen diesen doppelten Einträgen suchen lassen und mir jeweils , wenn vorhanden, die Zeilennummer des doppelten Eintrags in eine log-Datei analog zum Dateinamen (33204108.log, 33204109.log, ...) schreiben lassen.
Kann mir jemand helfen?
Vielen Dank für alle Vorschläge!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 110511
Url: https://administrator.de/forum/anfaengerfrage-zu-script-konstruktion-110511.html
Ausgedruckt am: 30.04.2025 um 05:04 Uhr
8 Kommentare
Neuester Kommentar
Moin mapauthor,
willkommen im Forum.
Da Dein Problem ein zu 90% nur manuell (nicht automatisierbar) zu lösendes Problem zu sein scheint, wäre der Vor-Filter-Aufwand eigentlich schon mit einer Zeile vom CMD-Prompt angefackelt.
Vorbereitung (einmalig) am CMD-Prompt:
dann:
So hast Du alle "doppelten" Data0-Zeilen auf dem Schirm.
Ich weiss nicht, ob der Aufwand lohnt, noch alle "Sections" rauszuschmeissen, die nur aus 3 Zeilen bestehen [POLYLINE], Data0=.., [END]?
Von wieviel Sections je Datei reden wir denn?
Grüße
Biber
willkommen im Forum.
Da Dein Problem ein zu 90% nur manuell (nicht automatisierbar) zu lösendes Problem zu sein scheint, wäre der Vor-Filter-Aufwand eigentlich schon mit einer Zeile vom CMD-Prompt angefackelt.
Vorbereitung (einmalig) am CMD-Prompt:
echo [POLYLINE]>>suchworte.txt
echo Data0=>>suchworte.txt
echo [END]>>suchworte.txt
dann:
>findstr /n /L /g:suchworte.txt D:\Ein\Dokument.txt
3:[POLYLINE]
10:Data0=(42.55619,8.97413),(42.55608,8.97386), [...] ,(42.55050,8.99999)
13:Data0=(42.54548,8.99999),(42.54539,8.99993), [...] ,(42.54001,8.99999)
15:[END]
....
So hast Du alle "doppelten" Data0-Zeilen auf dem Schirm.
Ich weiss nicht, ob der Aufwand lohnt, noch alle "Sections" rauszuschmeissen, die nur aus 3 Zeilen bestehen [POLYLINE], Data0=.., [END]?
Von wieviel Sections je Datei reden wir denn?
Grüße
Biber
Moin mapauthor,
Das beschriebene Verhalten...
Anyhow - ein nun etwas klarer erkennbarerer Lösungsweg ginge wohl in Richtung der sed-Utilitiys
Auch dazu haben wir einige Spezialisten hier im Forum - ich stell mich allerdings bei diesem Thema in die zweite Reihe.
Grüße
Biber
Das beschriebene Verhalten...
fängt danach an zu rennen und hört ohne Angabe zu Ergebnissen überhaupt nicht mehr auf zu laufen.
deutet IMHO darauf hin, dass- entweder Windows-konforme CRLFs/Zeilenendemarken fehlen (kommen die Daten von einem Unix-Server?)
- oder aber einzelne Zeilen zu lang für das Findstr.exe-Utiltily werden.
Anyhow - ein nun etwas klarer erkennbarerer Lösungsweg ginge wohl in Richtung der sed-Utilitiys
Auch dazu haben wir einige Spezialisten hier im Forum - ich stell mich allerdings bei diesem Thema in die zweite Reihe.
Grüße
Biber
Hallo mapauthor und Biber!
Da ich hinsichtlich "sed" auch nur Gelegenheitstäter bin, ein Versuch mit VBS:
Beim Aufruf anzugeben sind die zu untersuchende Datei sowie die Logdatei (diese wird nicht überschrieben, sondern ergänzt) - Beispiel:
Vereinfacht habe ich dahingehend, dass bei jeder mit "[POLYLINE]" beginnenden Zeile ohne Berücksichtigung eines folgenden "[END]" die Zählung der "Data0"-Zeilen neu beginnt. Außerdem gibt es für die übergebenen Dateien keine Überprüfung des Pfades bzw auf Vorhandensein (dies unter der Annahme, dass das Script von einem Batch aus einer Schleife über alle .mp-Dateien aufgerufen werden wird).
Grüße
bastla
Da ich hinsichtlich "sed" auch nur Gelegenheitstäter bin, ein Versuch mit VBS:
Suche = "Data0="
Start = "[POLYLINE]"
Datei = WScript.Arguments(0)
LogDatei = WScript.Arguments(1)
LSuche = Len(Suche)
LStart = Len(Start)
Set fso = CreateObject("Scripting.FileSystemObject")
Set Ein = fso.OpenTextFile(Datei)
Set Aus = fso.OpenTextFile(LogDatei, 8, True)
Aus.WriteLine Datei
Do While Not Ein.AtEndOfStream
Zeile = Ein.ReadLine
ZNr = ZNr + 1
If Left(Zeile, LStart) = Start Then
Anzahl = 0
ElseIf Left(Zeile, LSuche) = Suche Then
Anzahl = Anzahl + 1
If Anzahl > 1 Then Aus.WriteLine ZNr
End If
Loop
Aus.WriteBlankLines 2
Aus.Close
Ein.Close
cscript //nologo "D:\christian\GIS\_vbs\LogMultipleData0Lines.vbs" "D:\christian\GIS\_vbs\00.mp" "D:\christian\GIS\_vbs\Zeilen.log"
Grüße
bastla
Hallo mapauthor!
Dann auf einer etwas veränderten Basis:
Es wird in dieser Version nur mehr überprüft, ob "[POLYLINE]" in der Zeile enthalten ist - oben hatte ich noch die Position Zeilenanfang vorausgesetzt (was ev öfter nicht der Fall gewesen sein könnte, da ansonsten das nächstfolgende "Data0=" hätte übersprungen werden müssen).
Zusätzlich werden alle "Data0="-Zeilen, welche nach einem "[END]" und vor dem nächsten "[POLYLINE]" folgen, ignoriert. Außerdem erfolgt der Vergleich auf "[POLYLINE]" bzw "[END]" ohne Berücksichtigung von Groß-/Kleinschreibung.
Grüße
bastla
P.S.: Enden zB die "[POLYGON]"-Sections tatsächlich mit "[ENDE]" (groß oder klein geschrieben egal) und könnte das auch bei "[POLYLINE]"-Bereichen der Fall sein?
Dann auf einer etwas veränderten Basis:
Es wird in dieser Version nur mehr überprüft, ob "[POLYLINE]" in der Zeile enthalten ist - oben hatte ich noch die Position Zeilenanfang vorausgesetzt (was ev öfter nicht der Fall gewesen sein könnte, da ansonsten das nächstfolgende "Data0=" hätte übersprungen werden müssen).
Zusätzlich werden alle "Data0="-Zeilen, welche nach einem "[END]" und vor dem nächsten "[POLYLINE]" folgen, ignoriert. Außerdem erfolgt der Vergleich auf "[POLYLINE]" bzw "[END]" ohne Berücksichtigung von Groß-/Kleinschreibung.
Suche = "Data0="
Start = "[POLYLINE]"
Ende = "[END]"
Datei = WScript.Arguments(0)
LogDatei = WScript.Arguments(1)
LSuche = Len(Suche)
Set fso = CreateObject("Scripting.FileSystemObject")
Set Ein = fso.OpenTextFile(Datei)
Set Aus = fso.OpenTextFile(LogDatei, 8, True)
Aus.WriteLine Datei
Do While Not Ein.AtEndOfStream
Zeile = Ein.ReadLine
ZNr = ZNr + 1
If InStr(1, Zeile, Start, vbTextCompare) > 0 Then
Anzahl = 0
InSection = True
ElseIf InStr(1, Zeile, Ende, vbTextCompare) > 0 Then
InSection = False
ElseIf Left(Zeile, LSuche) = Suche Then
If InSection Then
Anzahl = Anzahl + 1
If Anzahl > 1 Then Aus.WriteLine ZNr
End If
End If
Loop
Aus.WriteBlankLines 2
Aus.Close
Ein.Close
bastla
P.S.: Enden zB die "[POLYGON]"-Sections tatsächlich mit "[ENDE]" (groß oder klein geschrieben egal) und könnte das auch bei "[POLYLINE]"-Bereichen der Fall sein?