Auslesen der drittletzten Zeile ..
Hallo zusammen,
ich habe nach einer ganzen Weile, mit Eurer Hilfe bei ähnlichen Problemen, mir ein funktionierendes Script gebastelt.
Mein Problem ist, dass je größer die Logdatei wird, der Durchlauf Ewigkeiten dauert.
Meine Frage, was könnte ich noch verbessern bzw. mir an Code sparen um das Script evtl. performanter zu machen?
Was macht das Script:
Eine Installationsroutine schreibt in ein vorgegebenes Logfile den akt. Status der Installation, sollte es einen Fehler geben oder fertig sein, wird am Ende der Logdatei eine Anweisung geschrieben.
Genau diese Anweisung möchte ich aus dem Log auslesen und mich darüber per Mail informieren lassen.
Das Problem, nachdem die Anweisung ins Log geschrieben wurde, werden noch zwei Leerzeilen angefügt, so dass ich nicht sagen kann, ließ mir die letzte Zeile aus.
Aus diesem Grund lasse ich das Script zwei mal durchlaufen. Im ersten Durchlauf wird die Anzahl der Zeilen ausgekundschaftet und 2 abgezogen. Im zweiten Lauf nun die "letzte" ausgelesen.
Ein weiteres Problem ist, wenn im ersten Lauf 388.082 Zeilen gezählt werden, die Datei aber in diesem Augenblick befüllt wird, evtl. sogar mit der ersehnten Anweisung, wird diese jedoch noch nicht im zweiten Lauf wahrgenommen, da ja die Zeile 388.080 ausgelesen wird. D.h. erst in einem weiteren kompletten Lauf wird die Anweisung erkannt, ausgewertet und mir eine E-Mail geschickt.
Ich hoffe Ihr könnt mir folgen, falls nicht, einfach fragen.
ps. könnte mir noch jmd erklären, was es mit ("Var=%~2") bei setvarFixLine auf sich hat?
Vielen Dank.
Gruß
Tobias
ich habe nach einer ganzen Weile, mit Eurer Hilfe bei ähnlichen Problemen, mir ein funktionierendes Script gebastelt.
Mein Problem ist, dass je größer die Logdatei wird, der Durchlauf Ewigkeiten dauert.
Meine Frage, was könnte ich noch verbessern bzw. mir an Code sparen um das Script evtl. performanter zu machen?
Was macht das Script:
Eine Installationsroutine schreibt in ein vorgegebenes Logfile den akt. Status der Installation, sollte es einen Fehler geben oder fertig sein, wird am Ende der Logdatei eine Anweisung geschrieben.
Genau diese Anweisung möchte ich aus dem Log auslesen und mich darüber per Mail informieren lassen.
Das Problem, nachdem die Anweisung ins Log geschrieben wurde, werden noch zwei Leerzeilen angefügt, so dass ich nicht sagen kann, ließ mir die letzte Zeile aus.
Aus diesem Grund lasse ich das Script zwei mal durchlaufen. Im ersten Durchlauf wird die Anzahl der Zeilen ausgekundschaftet und 2 abgezogen. Im zweiten Lauf nun die "letzte" ausgelesen.
Ein weiteres Problem ist, wenn im ersten Lauf 388.082 Zeilen gezählt werden, die Datei aber in diesem Augenblick befüllt wird, evtl. sogar mit der ersehnten Anweisung, wird diese jedoch noch nicht im zweiten Lauf wahrgenommen, da ja die Zeile 388.080 ausgelesen wird. D.h. erst in einem weiteren kompletten Lauf wird die Anweisung erkannt, ausgewertet und mir eine E-Mail geschickt.
Ich hoffe Ihr könnt mir folgen, falls nicht, einfach fragen.
@echo off
set "instlog=c:\inst.log"
set "anweisung=Waiting for an answer from GUI"
:start
:: Nummer der letzten Zeile ausfindig machen und zwei Zeilen abziehen (Leerzeilen im Log)
FOR /F "delims=:" %%A IN ('findstr /N .* "%instlog%"') DO set "zeile=%%A"
set /A "zeile=%zeile%-2"
:: Inhalt der Vorvorletzen Zeile in eine Variable einlesen
Set /a "cnt=1"
Set /a "n=%zeile%"
for /F "delims=" %%i in ('findstr /N .* "%instlog%"') do call :setvarFixLine %n% "%%i"
goto step1
:: Sprungmarke #setvarFixLine
:setvarFixLine
If %cnt%==%1 Set "Var=%~2"
Set /a "cnt+=1"
goto :eof
:: Sprungmarke #setvarFixLine
:step1
:: Inhalt der Variable (VAR) zurecht stutzen
set "var=%var:~-30,30%"
:: Inhalt der Variable mit dem gewünschten Zeileninhalt vergleichen
if "%var%" EQU "%anweisung%" goto gui_wait
goto start
:gui_wait
Ausgabe per Email ..
ps. könnte mir noch jmd erklären, was es mit ("Var=%~2") bei setvarFixLine auf sich hat?
Vielen Dank.
Gruß
Tobias
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 231100
Url: https://administrator.de/contentid/231100
Ausgedruckt am: 22.11.2024 um 01:11 Uhr
11 Kommentare
Neuester Kommentar
... oder etwas kürzer (ab Zeile 7)
Ansonsten noch ein Hinweis: Wenn die letzten beiden Zeilen leer sind, würde ein
in der Varaiablen %Zeile% den Inhalt der letzten nicht leeren Zeile liefern, wobei aber natürlich trotzdem einmal alle Zeilen durchlaufen werden müssten.
Grüße
bastla
findstr /ic:"%anweisung%" "%instlog%">nul || goto :start
echo Ausgabe Mail
for /f "usebackq delims=" %%i in ("%instlog%") do set "Zeile=%%i"
Grüße
bastla
moin,
var wird mit den zweiten Parameter, der in der forschleife übergeben wird, befüllt. Ist aber nicht sehr performant, da jede Zeilennummer für sich überprüft wird.
Alternativ:
@chris, er will doch die letzte gültige Zeile im LOG auslesen. Das wird wohl schon paarmal drinstehen.
[OT]
man diese Surface TastaturMatte ist echt gewöhnungsbedürftig ....
[/OT]
Gruß Phil
var wird mit den zweiten Parameter, der in der forschleife übergeben wird, befüllt. Ist aber nicht sehr performant, da jede Zeilennummer für sich überprüft wird.
Alternativ:
for /f %%i in (' "find /c /v "" <logfile.log" ') do set /a n = %%i -2
more +%n% logfile.log |find "%Anweisung%" && echo mach was....
@chris, er will doch die letzte gültige Zeile im LOG auslesen. Das wird wohl schon paarmal drinstehen.
@echo off
set "instlog=c:\inst.log"
set "anweisung=Waiting for an answer from GUI"
set "Anweisung=%Anweisung: =^ %"
:start
for /f "usebackq tokens=1-6" %%a in ("%instlog%") do if %%a^ %%b^ %%c^ %%d^ %%e^ %%f equ %Anweisung% (set OK=1) else set "OK="
if defined OK goto :gui_wait
goto :start
:gui_wait
rem Ausgabe per Mail ..
[OT]
man diese Surface TastaturMatte ist echt gewöhnungsbedürftig ....
[/OT]
Gruß Phil
@ PH
Grüße
bastla
Das wird wohl schon paarmal drinstehen.
Ist ja egal, wie oft - wenn das letzte Vorkommen gefragt ist, genügt eine Schleife über das "findstr
"-Ergbenis:set "Meldung="
for /f "delims=" %%i in ('findstr /ic:"%anweisung%" "%instlog%"') do set "Meldung=%%i"
if not defined Meldung goto :start
echo Mail mit %Meldung%
bastla
Hey,
Batch ist 1. langsam und 2. für grosse Textdateien nicht geeignet, weil da vieles wie zB die
Hier ein Beispiel für die "drittletzte" Zeile, wobei der Text nur einmal durchlaufen wird:
Hier wieder batchtypische Einschränkungen:
1) alle Ausrufezeichen werden gelöscht
2) funktioniert nicht mit utf-8/utf-16 bzw. Unicode
3) Leerzeilen werden nicht mitgezählt
Gruss.
Batch ist 1. langsam und 2. für grosse Textdateien nicht geeignet, weil da vieles wie zB die
For
Schleife nicht funktioniert. Nimm dann entweder eine andere Scriptsprache oder GNUWin32 for Windows.Hier ein Beispiel für die "drittletzte" Zeile, wobei der Text nur einmal durchlaufen wird:
@ECHO OFF &SETLOCAL disableDelayedExpansion
FOR %%a IN (*.txt) DO CALL:GetLine "%%~a"
GOTO:EOF
:GetLine
SETLOCAL enableDelayedExpansion
FOR /f "usebackqdelims=" %%b IN ("%~1") DO (
SET "LastButTwo=!SecondLast!"
SET "SecondLast=!Last!"
SET "Last=%%b"
)
ECHO(Drittletzte Zeile IN "%~1" ist:
ECHO(!LastButTwo!
EXIT /b
1) alle Ausrufezeichen werden gelöscht
2) funktioniert nicht mit utf-8/utf-16 bzw. Unicode
3) Leerzeilen werden nicht mitgezählt
Gruss.