Datei erstellen aus Textsuche in Datei

German support forum

Moderators: white, Hacker, Stefan2

Post Reply
T_a_u_r_e_c
Junior Member
Junior Member
Posts: 21
Joined: 2015-07-17, 06:28 UTC

Datei erstellen aus Textsuche in Datei

Post by *T_a_u_r_e_c »

Hallo,
ich habe ein kleines Problem mit einer Datei (xml) in der Fehler aufgelistet werden und ich hoffe das mir jemand helfen kann.

Die Struktur der Fehler in der xml Datei ist immer wieder gleich.
Ich brauche aus der Struktur den Teil in dem die Pfadangabe steht und möchte daraus eine Textdatei erstellen,
damit ich die aufgelisteten Dateien weiterbearbeiten kann (kopieren zum archivieren).
Mein Problem ist, das in der Pfadangabe auch mal nichts stehen kann (und damit die Klammer nicht mit Errorfile geschlossen wird )
Ich habe es mit folgendem Regex versucht komme aber nicht weiter. (weil ich keine Ahnung von Regex habe)

Im Prinzip will ich folgende abfrage machen:
Gib mir den Text zwischen Errorfile und Errorfile (Pfadangabe) wenn vorhanden
sonst zwischen Errorfile i: und ="true" /> (nil)
wiederhole bis Dateiende.

?siU(?(?=.*Errorfile>(.*)</d2p1:Errorfile).*Errorfile i:>(.*)="true" />)/S

Abfrage ist nur für 1 Ergebnis (und das nicht einmal richtig). Da die xml Datei (dynamische länge) täglich bis zu 47 Einträge haben kann (Scan)
weiss ich nicht wie ich für jeden vorhandenen Einträg eine Gruppe (Ergebnis) bekomme.

Struktur:

<?xml version="1.0" encoding="utf-8"?><QueryResultOfActivityLogEntryfxmKNYLZ xmlns:i="http://www.w3.org/2001/XMLSchema-instance" >
<Scan>
<TotalRecordCount>37903</TotalRecordCount>
<Items>
<d2p1:LogEntry>
<d2p1:Date>2018-01-17T22:49:39.4091573Z</d2p1:Date>
<d2p1:Id>2a6eefc101844386841c83c1f0fe398e</d2p1:Id>
<d2p1:ItemId i:nil="true"/>
<d2p1:Name>PC0108</d2p1:Name>
<d2p1:ShortOverview>IP Adresse: 192.0.0.68</d2p1:ShortOverview>
<d2p1:Type>Error</d2p1:Type>
<d2p1:Error>0f9fa52f242c46d5a1d5a3cdc010537c</d2p1:Error
<d2p1:Errorfile>c:\Users\admin\Documents\Fileanalysis\Errors\Errorfile20180117.txt</d2p1:Errorfile>
</d2p1:LogEntry>
<d3p1:Type>Scanfile</d3p1:Type>
<d3p1:UserData i:nil="true"/>
<d4p1:ExternalUrl>
<d4p1:Name>PC0108</d4p1:Name>
<d4p1:Url>https://PC0108.mynet</d4p1:Url>
</d4p1:ExternalUrl>
<d3p1:Overview i:nil="true"/>
</Items>
</Scan>
<Scan>
<TotalRecordCount>1784</TotalRecordCount>
<Items>
<d2p1:LogEntry>
<d2p1:Date>2018-01-17T22:57:32.4365790</d2p1:Date>
<d2p1:Id>7a6eefc101244326841c83c1f0fe328A</d2p1:Id>
<d2p1:ItemId i:nil="true"/>
<d2p1:Name>PC0175</d2p1:Name>
<d2p1:ShortOverview>IP Adresse: 192.0.0.138</d2p1:ShortOverview>
<d2p1:Type>Error</d2p1:Type>
<d2p1:Error>0</d2p1:Error
<d3p1:Errorfile i:nil="true" />
</d2p1:LogEntry>
<d3p1:Type>Scanfile</d3p1:Type>
<d3p1:UserData i:nil="true"/>
<d4p1:ExternalUrl>
<d4p1:Name>PC0175</d4p1:Name>
<d4p1:Url>https://PC0175.mynet</d4p1:Url>
</d4p1:ExternalUrl>
<d3p1:Overview i:nil="true"/>
</Items>
</Scan> <Scan>
<TotalRecordCount>16884</TotalRecordCount>
<Items>
<d2p1:LogEntry>
<d2p1:Date>2018-01-17T23:06:19.345125673Z</d2p1:Date>
<d2p1:Id>6a7bbfc101844386841c83c1f0ff322e</d2p1:Id>
<d2p1:ItemId i:nil="true"/>
<d2p1:Name>PC054</d2p1:Name>
<d2p1:ShortOverview>IP Adresse: 192.0.0.14</d2p1:ShortOverview>
<d2p1:Type>Error</d2p1:Type>
<d2p1:Error>0a9fa52f242c46d5a1d5a3cdc06677ac</d2p1:Error
<d2p1:Errorfile>c:\Users\administrator\Documents\Fileanalysis\Errors\Errorfile20180117.txt</d2p1:Errorfile>
</d2p1:LogEntry>
<d3p1:Type>Scanfile</d3p1:Type>
<d3p1:UserData i:nil="true"/>
<d4p1:ExternalUrl>
<d4p1:Name>PC054</d4p1:Name>
<d4p1:Url>https://PC054.mynet</d4p1:Url>
</d4p1:ExternalUrl>
<d3p1:Overview i:nil="true"/>
</Items>
</Scan>
</QueryResultOfActivityLogEntryfxmKNYLZ>




Ich hoffe es kann mir jemand helfen weil ich keine Lust mehr habe jeden Tag so viel Zeit zu investieren um die Dateien zu sichern.
Ich bedanke mich im Voraus für die Unterstüzung

cu Taurec
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

PowerShell: Extrahiere Zeilen aus Datei (Finde Suche Text)

Post by *Stefan2 »

Mit welchem Programm möchtest du denn diese XML bearbeiten?


Hier mal zum Start ein Beispiel mit Powershell:
(Ich habe mal den Namen der Errordatei in meiner 'Datei.xml' angepasst, um besser das Ergebnis inspizieren zu können)


PoSh v2 + PoSh v3

PS C:\temp> Get-Content .\Datei.xml | Select-String -Pattern 'Errorfile' | Select -ExpandProperty line

<d2p1:Errorfile>c:\Users\admin\Documents\Fileanalysis\Errors\Errorfile 01.txt</d2p1:Errorfile>
<d3p1:Errorfile i:nil="true" />
<d2p1:Errorfile>c:\Users\administrator\Documents\Fileanalysis\Errors\Errorfile 02.txt</d2p1:Errorfile>


PS C:\temp>


PS C:\temp> Get-Content .\Datei.xml | Select-String -Pattern 'Errorfile' | Select -ExpandProperty line | Out-File Result.txt
C:\temp>Result.txt



PoSh v3
PS C:\temp> (Select-String .\Datei.xm -Pattern 'Errorfile').Line | Set-Content Result2.txt






Natürlich kann man den Output auch noch formatieren und überflüssiges entfernen...

PS C:\temp> Get-Content .\Datei.xml | Select-String -Pattern 'Errorfile' | Select -ExpandProperty line | ForEach{$_ -replace"<.+?>"} |Out-File Result3.txt

c:\Users\admin\Documents\Fileanalysis\Errors\Errorfile 01.txt

c:\Users\administrator\Documents\Fileanalysis\Errors\Errorfile 02.txt





 
T_a_u_r_e_c
Junior Member
Junior Member
Posts: 21
Joined: 2015-07-17, 06:28 UTC

Post by *T_a_u_r_e_c »

Hallo Stefan2

wow, erst einmal herzlichen Dank für Deine schnelle Antwort.
Das Powerscript würde mich schon helfen aber ich würde eine
Regex Abfrage bevorzugen, da ich das in vorhandene Scripten einbinden kann.

Bis dahin werde ich mal ein bissle mit dem PS Script "spielen"

cu Taurec
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Re: Datei erstellen aus Textsuche in Datei

Post by *milo1012 »

2T_a_u_r_e_c
Da das kein spezifisches TC-Problem ist, solltest du zumindest sagen, was du für diese Aufgabe (bisher) verwendest.
Dein bisheriger RegEx sieht Perl-kompatibel aus, also würde dieser hier wohl so funktionieren, wie du es beschrieben hast:

Code: Select all

(?|<([^/]+Errorfile)>([^<>]+)</\g{1}>|<([^/]+Errorfile).*?(nil)=.*?/>)
Das Ergebnis steht dann in der zweiten Gruppe, also je nach Programm $2 oder \2.

Wenn ich deinen Threadtitel ("Datei erstellen aus Textsuche in Datei") wortwörtlich nehme,
dann wäre z.B. mein RegXtract-Plugin genau für so eine Aufgabe gedacht, mein RegEx-Vorschlag von oben würde damit auch funktionieren.
TC plugins: PCREsearch and RegXtract
T_a_u_r_e_c
Junior Member
Junior Member
Posts: 21
Joined: 2015-07-17, 06:28 UTC

Post by *T_a_u_r_e_c »

Hallo milo1012,
vielen Dank für Deine Antwort.
Momentan gehe ich "händisch" vor (Datei öffnen, nach Pfad suchen, im Hintergrund Datei kopieren ...)
Ich konnte die Abfrage in der Firma ausprobieren.
Leider bekomme ich hier nur zwei Ergebnisse angezeigt (1. Gruppen = Nil und in der 2. Gruppe steht der dritte Pfad)

Leider kann ich Dir nicht sagen zu welcher Kompatibilität das Ganze sein muss, da die hier verwendete Software schon sehr alt ist und die Firma die das installiert hat nicht mehr existent ist. (Hatte gehofft das mit der Umstellung auf Windows 10 da Thema erledigt wäre, aber Pustekuchen)
Hättest Du Zeit und Lust mir Deine Abfrage zu erklären? Ich würde dann versuchen selber weiter zu machen.

cu Taurec
ups.... mein Boss ist da :-(
User avatar
Stefan2
Power Member
Power Member
Posts: 4133
Joined: 2007-09-13, 22:20 UTC
Location: Europa

Post by *Stefan2 »

T_a_u_r_e_c wrote:... ich würde eine
Regex Abfrage bevorzugen,
...

in Ordnung, ein weiterer Schritt...


Betroffene Zeile erkennen:
Get-Content .\Datei.xml | ForEach-Object{IF($_ -like "*Errorfile*"){$_}}

Code: Select all

PS>gc .\Datei.xml|%{IF($_ -like "*Errorfile*"){$_}}
<d2p1:Errorfile>c:\Users\admin\Documents\Fileanalysis\Errors\Errorfile20180117.txt</d2p1:Errorfile>
<d3p1:Errorfile i:nil="true" />
<d2p1:Errorfile>c:\Users\administrator\Documents\Fileanalysis\Errors\Errorfile20180117.txt</d2p1:Errorfile>

PS>

Betroffene Zeile erkennen und gleich die spitzen Klammern entfernen:
Get-Content .\Datei.xml | ForEach-Object{IF($_ -like "*Errorfile*"){$_ -replace "<.+?>"}}

Code: Select all

PS>gc .\Datei.xml|%{IF($_ -like "*Errorfile*"){$_ -replace "<.+?>"}}
c:\Users\admin\Documents\Fileanalysis\Errors\Errorfile20180117.txt

c:\Users\administrator\Documents\Fileanalysis\Errors\Errorfile20180117.txt

PS>



Was noch? :D
 
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

T_a_u_r_e_c wrote: Momentan gehe ich "händisch" vor (Datei öffnen, nach Pfad suchen, im Hintergrund Datei kopieren ...)
Ohne weitere Details (Programmname oder dahintersteckende Such-Engine) ist es schwierig, da noch weiter zu helfen.
T_a_u_r_e_c wrote: Leider bekomme ich hier nur zwei Ergebnisse angezeigt (1. Gruppen = Nil und in der 2. Gruppe steht der dritte Pfad)
Was eigentlich nicht sein kann. Offenbar hat das Programm den RegEx akzeptiert, aber ist gibt keinen formalen Unterschied zwischen dem ersten und dritten Dateipfad im OP. Also entweder erzeugt das Programm Blödsinn, oder du benutzt eine andere Datei als die, die du im OP gepostet hast (da ist sowieso ein Fehler drin, </d2p1:Error ist nicht mit schließender Klammer versehen). Wenn ich das in Programmen mit zu Perl kompatibler RegEx teste bekomme ich alle drei Ergebnisse.
T_a_u_r_e_c wrote: Hättest Du Zeit und Lust mir Deine Abfrage zu erklären? Ich würde dann versuchen selber weiter zu machen.
Dann kurz und kompakt:
Beide Möglichkeiten (normaler Dateipfad oder der alleinstehende XML-Tag mit nil) stehen in der globalen Klammer und sind mit dem Pipe-Symbol getrennt.
Die Pipe am Beginn sagt zusätzlich: setzte die Zählung der Sub-Gruppen ("Teilausdrücke) in jeder Alternative zurück, also Beginne die Zählung wieder von eins. Das alleinstehende XML-Tag ist denke ich selbsterklärend. In der anderen Alternative heißt es nichts weiter, als:
zwischen einer öffnenden und schließendem spitzen Klammer gibt es beliebig viele Zeichen und dann am Ende die Zeichenkette "Errorfile".
Der selbe String (referenziert mit \g{1} ) muss im schließendem Tag vorkommen, allerdings dann mit vorangestelltem Slash.
Dazwischen gibt es eine beliebige Zeichenkette, welche lediglich nicht aus öffnender und schließender spitzen Klammer bestehen darf.
TC plugins: PCREsearch and RegXtract
T_a_u_r_e_c
Junior Member
Junior Member
Posts: 21
Joined: 2015-07-17, 06:28 UTC

Post by *T_a_u_r_e_c »

Erst einmal herzlichen Dank an Euch beiden.

#milo1012
Ich hatte mich vertan mit meiner Aussage über den Gruppen inhalt.
In der ersten Gruppe steht d3p1:Errorfile und das Ergebnis steht in der 2ten Gruppe
Soweit so gut, leider aber immer nur der erste gefundene Eintrag.
Ich kann die Abfrage aber nur einmal machen (und nicht weiterlaufen lassen).
Mein Ziel war es alle Pfade in der Datei zu finden und mir als Ergebnis anzeigen zu lassen (z.B. 24 Einträge = 24 Gruppen mit den jeweiligen Pfaden oder NiL)
Ich werde mal schauen ob ich das hinbekomme (ich bezweifen das mal ganz stark) :-)


#Stefan2
Dein PS Script funktioniert Klasse .
Ich muss zwar in der Firma und mein Rechner muss an sein da ich leider keine PS Script auf dem Server (wo die Datei liegt) ausführen kann.
aber damit kann ich erst einmal arbeiten :-)


cu Taurec
P.S. noch einmal herzlichen Dank für Eure Bemühungen
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

T_a_u_r_e_c wrote:Ich kann die Abfrage aber nur einmal machen (und nicht weiterlaufen lassen).
Mein Ziel war es alle Pfade in der Datei zu finden und mir als Ergebnis anzeigen zu lassen (z.B. 24 Einträge = 24 Gruppen mit den jeweiligen Pfaden oder NiL)
Okay, langsam verstehe ich, was du eigentlich vorhast. Allerdings ist mir immer noch nicht klar, warum du alles in einem einzigen (ersten) Suchergebnis haben musst, statt die Suche automatisch da fortzusetzen zu lassen, wo sie das letzte Ergebnis fand, aber wie dem auch sei.
So ein Konstrukt ist natürlich möglich, aber praktisch ziemlich "unschön":

Code: Select all

(?si)(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>).*?(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>).*?(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>)
Das würde jetzt die ersten drei Ergebnisse in der Datei finden, du kannst die anderen Gruppen gerne selbst ergänzen (immer das selbe Muster wiederholen).
TC plugins: PCREsearch and RegXtract
T_a_u_r_e_c
Junior Member
Junior Member
Posts: 21
Joined: 2015-07-17, 06:28 UTC

Post by *T_a_u_r_e_c »

#milo1012
Die letzte Abfrage funktioniert. Ich bekomme 3 Ergebnisse (Gruppen) angezeigt.
(Du wirst es nicht glauben, ich hatte mit der gleichen Abfrage auch schon eperimentiert :-)
Ich muss jetzt nur noch zählen wie oft die Einträge vorhanden sind und dann die Abfrage entsprechend erweitern sonst bekomme ich einen Fehler (wenn ich mehr Abfragen als Einträge mache)

cu Taurec
P.S. Es ist schon ganz schön mühselig in einer vorhanden Software he­r­um­dok­tern ohne das man eine Beschreibung hat. (Es gibt ja auch keinen mehr den man fragen kann :-(
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

T_a_u_r_e_c wrote:Ich muss jetzt nur noch zählen wie oft die Einträge vorhanden sind und dann die Abfrage entsprechend erweitern sonst bekomme ich einen Fehler (wenn ich mehr Abfragen als Einträge mache)
Das lässt sich ja auch flexibel machen, ohne per Hand zählen zu müssen, indem man sämtlich Gruppen nach der ersten optional macht:

Code: Select all

(?si)(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>)(?:.*?(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>))?(?:.*?(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>))?(?:.*?(?|<[^/]+Errorfile>([^<>]+)</[^>]+Errorfile>|<[^/]+Errorfile.*?(nil)=.*?/>))?
TC plugins: PCREsearch and RegXtract
Post Reply