kranzfr3d
Goto Top

Bestimmen Bereich einer txt-Datei suchen, den bereich dahinter kopieren und in eine neue Datei einlesen

muss nicht unbedingt mit ausschließlich per Batch funktionieren...

Moin, ich hab schon viel versucht, aber alles schlug fehl oder gab nicht das gewünschte Ergebnis.
Es handelt sich um log-Dateien (die mit Editor dem Editor zu öffnen gehen. Diese werden durch ein anderes Programm generiert.

In diesen log-Dateien (Datei.log; Datei.log1 usw.) möchte ich eine (vorzugsweise) Batchdatei nach "dataB=" suchen lassen. Dahinter steht i.d.R eine Nummer.
Es gibt auch Fälle, in denen dahinter nichts steht. In diesen soll die Suche das ignorieren und nichtvorhanden Wert quasi überspringen.
Evtl. hilfreich: Nach dieser Nummer gehts mit "dataC=" weiter.

Diese Nummern (die jedesmal unterschiedlich lang sind) sollen in eine neue Textdatei geschrieben werden. Diese Textdatei soll Zeilenweise durchnummeriert werden. In jede Zeile soll also jeweils einmal die Nummerrierungnummer und eine gefundene "dataB=" Nummer:
1 123456789
2 987523
usw.


(hier in dieser Datei sollen die "übersprungenen Werte" nicht als leere Felder angezeigt werden, also nicht:34 9652145 369856 7 2368955also 3 und 7 sind leer. So soll das nicht aussehen.)

Nach dem Vorgang soll die neu generierte Textdatei angezeigt werden.


Ich danke euch schonmal für weiterführende Ratschläge und evtl. Programme!


Schöne Grüße aus Berlin!

Content-ID: 96573

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

Ausgedruckt am: 25.11.2024 um 20:11 Uhr

llowartz
llowartz 10.09.2008 um 13:35:09 Uhr
Goto Top
Hallo Kranzfr3d,

Also ... wenn es sich um mehrere .log Dateien handelt die du ausliest, brauchst du erst mal eine schleife um al die Dateien zu identifizieren.

for %i in (c:\*.bat) do echo %i

Da du bei jeder Datei eine Anweisung (Suchen u. Einfügen) machen willst, schlag ich vor das du mehrere Prozess Dateien verwendest.

Also, Datei1 (Steuerdatei): Datei1.cmd
for %%i in (c:\*.bat) do call Datei2.cmd %%i

In Datei2 brauchst du eine schleife um den Inhalt der Datei auszulesen die du aus Datei1 übergibst (%%i)
for /F %%j in (%%i) do echo %%j >Test.txt
find "dataB=" h:\test.txt >eval.txt

Alle einträge die du suchst sollte jetzt in die Datei Test.txt sein ... nun noch dataB ausschneiden und die Nummern hinzufügen. Da in Batch keine Mathematische funk. gemacht werden können, muss du noch eine Datei anlegen (mit die Zahlen 1 bis soviel einträge du möchte in deine Logdateien hast) Die Datei nennen wir Liste.txt

die Datei Liste.txt
1
2
3
4
5

Finale Datei! In die Datei evaluate werden die einträge in die Datei eval.txt gefiltert und die Einträge in die Datei Liste.txt hinzugefügt.

for /F %%i in (%%i) do (
for /F %%j in (Liste.txt) do echo %%j %%i>Final.txt
)

Ich hoffe ich konnte helfen

Grüße
Lukas Lowartz
bastla
bastla 10.09.2008 um 14:49:32 Uhr
Goto Top
Hallo Kranzfr3d und willkommen im Forum!

Eine etwas andere Variante könnte so aussehen:
@echo off & setlocal enabledelayedexpansion
set "Dateien=D:\Deine Logs\Datei.log*"  
set "Liste=D:\Liste.txt"  
set "Suche=dataB="  

if exist "%Liste%" del "%Liste%"  
set /a Nr=0
for /f "tokens=2 delims==" %%i in ('findstr /i /b "%Suche%" "%Dateien%"') do set /a Nr+=1 & >>"%Liste%" echo !Nr! %%i  
notepad "%Liste%"  
Vorausgesetzt habe ich dabei (was Du nicht eindeutig beschrieben hast), dass "dataB=" am Beginn einer Zeile steht und dahinter nur die Nummer (oder gar nichts mehr) aufscheint.

Verwendet wird "findstr" zum Heraussuchen der passenden Zeilen, und eine "for"-Schleife, welche zur Zerlegung der Zeile das "=" benutzt und aus der so aufgeteilten Zeile den Teil ("token") 2 verwendet.

Um innerhalb der Schleife immer den aktuellen Wert der Zählervariable %Nr% zu erhalten, wird "delayedExpansion" (und dadurch bedingt die Schreibweise !Nr! anstatt %Nr%) eingesetzt.

Grüße
bastla
Kranzfr3d
Kranzfr3d 10.09.2008 um 14:58:08 Uhr
Goto Top
@Lukas Lowartz
Danke für deinen Beitrag!
Ich das ist eine tolle Idee, ur leider blicke ich nicht durch, wie viele Dateien ich nun brauche!
In welche Datei soll ich die erste Zeile
for %i in (c:\*.bat) do echo %i
einfügen?

@bastla
Die Idee find ich auch nicht schlecht, vor allem, da sie kompakter ist!
Aber leider ist genau das der Fall!
Der gesuchte Eintrag steht zu meinem bedauern in einer Zeile mittendrin. Kann die Suche dahingehend umgeschrieben werden?
Schrieb ich nicht, dass dahinter noch etwas kommt? Es geht anschließen (nach der Nummer durch ein Komma und Leerzeichen getrennt weiter mit "dataC=..."

Eine Zeile sieht etwa wie folgt aus:
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=123456, dataC=1, dataD=, dataE=

Danke, dass ihr euch meiner, VOR ALLEM so schnell, angenommen habt!

Grüße
bastla
bastla 10.09.2008 um 15:47:47 Uhr
Goto Top
Hallo Kranzfr3d!

Schrieb ich nicht, dass dahinter noch etwas kommt?
Deine Formulierung war
Evtl. hilfreich: Nach dieser Nummer gehts mit "dataC=" weiter.
was sich auch auf die nächste Zeile hätte beziehen können ...
Da die Zerlegung einer Zeile mittels Batch etwas aufwändig werden kann, ziehe ich in solchen Fällen die Verwendung von (temporärem) VBScript vor. Das könnte dann so aussehen:
@echo off & setlocal enabledelayedexpansion
set "Dateien=D:\Deine Logs\Datei.log*"  
set "Liste=D:\Liste.txt"  
set "Beginn=dataB="  
set "Ende=,"  

set F=%temp%\FindNumber.vbs
>%F%  echo T=WScript.Arguments(0)
>>%F% echo pre="%Beginn%"  
>>%F% echo post="%Ende%"  
>>%F% echo Set rE=New RegExp
>>%F% echo rE.Pattern=pre ^& "[0-9]*" ^& post  
>>%F% echo rE.IgnoreCase=True
>>%F% echo rE.Global=True
>>%F% echo Set Erg=rE.Execute(T)
>>%F% echo For Each E In Erg
>>%F% echo WScript.Echo Replace(Replace(E,pre,""),post,"")  
>>%F% echo Next

if exist "%Liste%" del "%Liste%"  
set /a Nr=0
for /f "delims=" %%i in ('findstr /i "%Beginn%" "%Dateien%"') do (  
    for /f %%a in ('cscript //nologo %F% "%%i"') do set /a Nr+=1 & >>"%Liste%" echo !Nr! %%a  
)
notepad "%Liste%"  
Um das eingebettete Script leichter nachvollziehbar zu machen, habe ich es auf mehrere Zeilen verteilt. Aufgabe des Scripts ist es, die vom Batch übergebene Zeile unter Verwendung "Regulärer Ausdrücke" zu durchsuchen, den relevanten Teil (die Nummer zwischen den in den Variablen "pre" und "post" - übernommen von den Batchvariablen %Beginn% und %Ende% - festgelegten Begrenzungen "dataB=" und Komma) zu isolieren und an den Batch als Ausgabe zurückzuliefern.

Die Scriptvariablen "pre" und "post" wären übrigens nicht unbedingt erforderlich, sollten aber eine ev Anpassung bzw Wiederverwendbarkeit erleichtern ...

Grüße
bastla
Kranzfr3d
Kranzfr3d 10.09.2008 um 16:32:36 Uhr
Goto Top
Danke für die vorteffliche Antwort,das beeindruckt mich ja ungemein face-smile
Nur leider scheint das VBS-Script fehlerhaft.
Es wird angelegt, alles supi usw, nur erscheint in dem CMD-Fenster bis zum Abbruch meinerseits immer wieder erneut zeilenweise "Das Gerät ist nicht bereit."
Wenn ich FindNumber.vbs im Temp-Verzeichnis manuell ausführen möchte, kommt die Fehlermeldung in Zeile 1 und Zeichen 1: Index außerhalb des gültigen Bereichs.
Code 800A0009
Laufzeitfehler eben face-sad

Ich hoffe, dies hilft dir (und mir) weiter!


Grüße


PS.: Im gleich Zuge möchte ich fragen wie ich bei
set "Dateien=C:\Datei.log"
mehrere Datein eintagen soll.
set "Dateien=C:\Datei.log, Datei2.log, datei3.log" funktioniert leider nicht...
bastla
bastla 10.09.2008 um 18:34:17 Uhr
Goto Top
Hallo Kranzfr3d!

Gleich zur Angabe der Dateien: Ich war zwar etwas verwundert, dass (lt Deinem Beispiel oben: Datei.log; Datei.log1 usw.) die Nummerierung an den Dateityp angefügt würde, habe Dir aber einfach geglaubt und daher die Dateien mit
set "Dateien=D:\Deine Logs\Datei.log*"  
also einem "*" am Ende vorgegeben. Wenn es nun doch "Datei.log", "Datei2.log", "datei3.log" usw sein sollen, einfach den Stern verlagern:
set "Dateien=D:\Deine Logs\Datei*.log"  
Die "for"-Schleife erledigt den Rest.
Nun zum Script: Aufgerufen wird dieses mit Übergabe eines Parameters, nämlich der auszuwertenden Textzeile. Wenn Du daher einen Test durchführen willst, dann (an der Kommandozeile) so:
cscript //nologo %temp%\FindNumber.vbs "2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=123456, dataC=1, dataD=, dataE=" 
Als Ergebnis solltest Du dann
123456
erhalten.

Um den gesamten Batch-Ablauf nachvollziehen zu können, ändere das "echo off" in ein "echo on" und starte den Batch ebenfalls von der Kommandozeile aus. Es wird dann jeder Befehl vor der Ausführung angezeigt, und Du solltest auf diese Art herausfinden können, wo das Problem liegt.
[Edit] Nochmals getestet:
Mit der folgenden Datei (als "C:\Datei.log" gespeichert)
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=123456, dataC=1, dataD=, dataE=
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=, dataC=1, dataD=, dataE=
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=1234567, dataC=1, dataD=, dataE=
erhalte ich mit dem (nur hinsichtlich des Speicherortes auf "C:\Datei*.log" angepassten) Batch von oben folgende Ergebnisdatei:
1 123456
2 1234567
Lege ich dann noch folgende "Datei2.log" an
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB= , dataC=1, dataD=, dataE=
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=555333, dataC=1, dataD=, dataE=
2008-09-10 14:34:15,805 [ReadThread] dataA=13501, dataB=00000 , dataC=1, dataD=, dataE=
wird (da nur die zweite Zeile eine der Spezifikation entsprechende Nummer enthält - in Zeile 3 befindet sich vor dem Komma ein Leerzeichen) diese Ausgabedatei erstellt:
1 123456
2 1234567
3 555333
Vielleicht kannst Du das erfolgreich nachvollziehen und dann ev Unterschiede zu Deinen realen Daten finden ...
[/Edit]

Grüße
bastla
Kranzfr3d
Kranzfr3d 10.09.2008 um 21:34:51 Uhr
Goto Top
Okay, das klingt alles ganz super face-big-smile
Sieht auch gut aus...man, du machst dir ja voll die Mühen...find ich voll Klasse und du sollst wissen, dass ich dir unendlich dankbar bin! Du überraschst mich mit jedem Post wieder aufs Neue!
Die Dateinamen hatte ich bei meinem letzten Post nur noch schnell hingetippt, weil ich ins Meeting musste. Gültig sind die von meinem ersten Post. Tut mir leid, dass ich dich verwirrt habe. Ursprünglich hatte ich den Stern falsch interpretiert. Deswegen meine Verwirrung; aber gut, dass du Klarheit geschaffen hast! Danke sehr!

Ok, du hast mittlerweile herausgefunden, dass ich nicht so tiefgründiges Wissen habe wie du mit den Batches - allerdings bin ich kein völliger Newbie...
Nur solltest du wissen, dass auch Sekretärinnen diesen Aufruf starten sollen!
Evtl. könntest du den Aufruf jetzt so kombinieren, dass die Logs auf einen Klick abgefragt werden können?

Ich bin ab morgen auf Dienstreise und erst wieder Montag im Büro um die Batches zu testen. Ich hätte nicht gedacht, dass so schnell eine Lösung herbeigeführt werden könnte!!!
Dann kann ich die Datei, wie du schon sagtest, an die Gegebenheiten anpassen! Ich hoffe zwar, dass ich keine Rückfragen habe, aber nur damit du Bescheid weißt *grins*


1000 Dank
bastla
bastla 10.09.2008 um 21:47:46 Uhr
Goto Top
Hallo Kranzfr3d!
Evtl. könntest du den Aufruf jetzt so kombinieren, dass die Logs auf einen Klick abgefragt werden können?
Leider verstehe ich nicht wirklich, was Du damit meinst - eigentlich sind tatsächlich nur die Zeilen 2 bis 5 anzupassen. Sobald der Batch auch bei Dir funktioniert, genügt dann ein Doppelklick ...

Und, nur zur Sicherheit: Das VBScript wird durch den Batch erstellt und aus dem Batch passend aufgerufen - darum muss sich also eigentlich niemand mehr kümmern. Gestartet werden muss einzig und allein der Batch.

Grüße
bastla
Kranzfr3d
Kranzfr3d 10.09.2008 um 22:54:42 Uhr
Goto Top
Naja deswegen:
Zitat von @bastla:
Nun zum Script: Aufgerufen wird dieses mit Übergabe eines Parameters, nämlich der auszuwertenden Textzeile. Wenn Du daher einen Test durchführen willst, dann (an der Kommandozeile) so:
cscript //nologo %temp%\FindNumber.vbs "2008-09-10 
14:34:15,805 [ReadThread] dataA=13501, dataB=123456, dataC=1, dataD=,
dataE="  
Also ich bin relativ verwirrt gerade. Ich hatte nämlich die Variablen schon mal angepasst, dachte ich zumindest. Evtl. war das fehlerhaft. Wenns bei dir geht werd ich das auch schon hinbekommen!
Und wenn nich hoffe ich, dass du dann noch da draußen bist und mir hilfst face-wink

also, dann bis Montag vielleicht *grins*


Grüße!
bastla
bastla 10.09.2008 um 23:05:46 Uhr
Goto Top
Hallo Kranzfr3d!

Nur, um das abzuschließen:
Naja deswegen:
Zitat von @bastla:
Nun zum Script: Aufgerufen wird dieses mit Übergabe eines
Parameters, nämlich der auszuwertenden Textzeile. Wenn Du daher
einen Test durchführen willst, dann (an der Kommandozeile) so:
war die Antwort auf:
Wenn ich FindNumber.vbs im Temp-Verzeichnis manuell ausführen möchte, kommt die Fehlermeldung in Zeile 1 und Zeichen 1: Index außerhalb des gültigen Bereichs.
Da es ja sinnvoll ist, einzelne Bestandteile zu testen, wollte ich Dich in dieser Hinsicht unterstützen - ansonsten wird, wie oben erwähnt, der Aufruf samt Parameterübergabe durch den Batch erledigt.

also, dann bis Montag vielleicht *grins*
Kein Problem ... (muss aber nicht sein face-wink)

Grüße
bastla
Kranzfr3d
Kranzfr3d 15.09.2008 um 07:37:08 Uhr
Goto Top
Das Skript funktioniert super! Das Skript ist schlecht hin der Burner, und du bist das auch!!!
Danke dir!!!
So, ich glaube, genug der Worte, wollen wir den Thread mal abschließen!

Also:
Vielen Lieben Dank nochmals an
llowartz
und
bastla
!!!

Grüße