mapauthor
Goto Top

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:

; 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!

Content-Key: 110511

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

Ausgedruckt am: 28.03.2024 um 19:03 Uhr

Mitglied: Biber
Biber 04.03.2009 um 13:57:05 Uhr
Goto Top
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:
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
Mitglied: mapauthor
mapauthor 04.03.2009 um 16:35:14 Uhr
Goto Top
Hallo Biber,

danke für die schnelle Antwort!

In Anlehnung an Deinen Vorschlag habe ich in einer Stapelverarbeitungsdatei die zeilen

FINDSTR /N /L /C:"Data0=" D:\christian\GIS\_findstr\00.mp

eingefügt und gestartet. cmd.exe fängt danach an zu rennen und hört ohne Angabe zu Ergebnissen überhaupt nicht mehr auf zu laufen.

Genaueres noch zu meiner Ausgangssituation:
Ich habe ca. 100 Dateien (*.mp) und jede Datei enthält bis zu 100000 Zeilen Text/Code. In den Zeilen, welche mit Data0= beginnen, stehen zwischen den runden Klammern Koordinatenangaben, die die Linien in einer Vekktorkarte beschreiben. Diese Angaben sind in jeder 'Section' unterschiedlich und mitunter sind dies pro 'Section' auch mal aberhunderte von Ausdrücken. Im Beispiel hatte ich vollständige Wiedergabe verzichtet.

Meine Vorstellung wäre, dass nur für den Fall das in einer der vielen 'Sections' zwischen [POLYLINE] und [END] der Eintrag Data0= doppelt auftaucht ich eine Zeilennummer geliefert bekomme bezogen auf doppelten Eintrag.

Gibt es weitere Ideen?
Für hilfe wäre ich sehr dankbar...
Mitglied: Biber
Biber 04.03.2009 um 16:50:40 Uhr
Goto Top
Moin mapauthor,

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
Mitglied: mapauthor
mapauthor 04.03.2009 um 17:37:48 Uhr
Goto Top
Hallo Biber,

Zeilenenden sind CRLF. Danke soweit...

Grüsse
Mitglied: bastla
bastla 04.03.2009 um 18:28:02 Uhr
Goto Top
Hallo mapauthor und Biber!

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
Beim Aufruf anzugeben sind die zu untersuchende Datei sowie die Logdatei (diese wird nicht überschrieben, sondern ergänzt) - Beispiel:
cscript //nologo "D:\christian\GIS\_vbs\LogMultipleData0Lines.vbs" "D:\christian\GIS\_vbs\00.mp" "D:\christian\GIS\_vbs\Zeilen.log"
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
Mitglied: mapauthor
mapauthor 04.03.2009 um 19:52:52 Uhr
Goto Top
Hallo Bastla!

Vielen Dank für die Mühe!

Ich verstehe zwar nur Bahnhof, ich habe das Script aber gerade zum Laufen gebracht.

Im Ansatz passiert, was ich mir erhofft habe: In der Log-Datei stehen zeilenweise Nummern von Zeilen, in denen das Element Data0= enthalten ist:

D:\christian\GIS\_vbs\00.mp
5788
5797
5807
5817
5827
5837
5846
5856
...

Problem noch: Es wird jedes Data0= Element ausgegeben und zwar nicht nur wenn es doppelt zwischen [POLYLINE] und [End] vorhanden ist. Zudem werden Einträge, welche in einer ähnlichen Section liegen, die mit [POI]...[Ende] bzw. [POLYGON]...[Ende] makiert sind ebenfalls mit ausgegeben. Kann man dagegen etwas tuen?

Freue mich über jeden Vorschlage, Danke!
Mitglied: bastla
bastla 04.03.2009 um 20:25:33 Uhr
Goto Top
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.
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
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?
Mitglied: mapauthor
mapauthor 04.03.2009 um 21:42:39 Uhr
Goto Top
Hallo Bastla!

Nocheinmal vielen Dank für die Mühe!

Ich habe die neue Version gerade testweise laufen lassen und es scheint wie erhofft zu funktionieren. Selbst bei einer Datei mit über 2,5 Mio Zeilen läuft es stabil und das Log-File wird mit Beginn eines Durchlaufs auf einer neuen Datei einfach unter Angabe des neuen Dateinamen erweitert. Toll!
Auf die Frage im PS: Sowohl die zu durchsuchenden Sections mit [POLYLINE], als auch die zu ignorierenden Sections [Polygon] und [POI] enden jeweils bevor die nächste Section beginnt mit [END]. Der Ausdruck innerhalb der eckigen Klammern ist dabei in Großbuchstaben.

Nochmals vielen an Dich und Biber!

Einen schönen Abend...

Grüße
mapauthor