Batch - Ein logfile auf änderungen prüfen und in den letzten Zeilen nach MEHREREN BESTIMMTEN einträgen suchen?
Hallo,
Ich benötige eine Abfrage die überprüft ob die Datei workshop_log.txt sich verändert hat.
Falls das Logfile sich verändert hat, befinden sich im unteren Teil der Datei ein paar Einträge,
die für mich interessant sind. Die reihenfolge ist hierbei zu beachten.
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error
(Die X stehen für eine Mod-ID)
Falls diese Einträge gefunden wurden sollen bestimmte Ordner (ID) & Unterordner gelöscht
werden, damit eine andere Batch die ich bereits erstellt habe, die neuen Items convertieren
kann. Gleichzeitig muss diese ID für weitere Abfragen in einem Textdokument gesichert werden.
Ich habe bereits ein System in der Richtung laufen, man könnte es wohl die Beta nennen.
Allerdings ist mein altes System anfällig für störungen, dazu auch noch langsam und nicht
vollautomatisiert. Das neue System soll alle 5 Minuten checken ob ein Update für eine
Modifikation rein kam. Danach die alten konvertierten Ordner löschen. Eine neue Konvertierung
starten, das ganze verpacken und danach einem zweiten Server (Linux) das "GO" zum Download
dieser gepackten Datei geben. Dort wird sie dann entpackt und zu ihrem Anwendungsort gebracht.
Soweit habe ich alles zur Hand. Auch unter dem Linux system wurde bereits alles vorbereitet.
Nun bin ich in Windows nicht so fit und weiß deshalb nicht was ich equivalent zu tail & grep
verwenden kann.
Ich benötige eine Abfrage die überprüft ob die Datei workshop_log.txt sich verändert hat.
Falls das Logfile sich verändert hat, befinden sich im unteren Teil der Datei ein paar Einträge,
die für mich interessant sind. Die reihenfolge ist hierbei zu beachten.
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error
(Die X stehen für eine Mod-ID)
Falls diese Einträge gefunden wurden sollen bestimmte Ordner (ID) & Unterordner gelöscht
werden, damit eine andere Batch die ich bereits erstellt habe, die neuen Items convertieren
kann. Gleichzeitig muss diese ID für weitere Abfragen in einem Textdokument gesichert werden.
Ich habe bereits ein System in der Richtung laufen, man könnte es wohl die Beta nennen.
Allerdings ist mein altes System anfällig für störungen, dazu auch noch langsam und nicht
vollautomatisiert. Das neue System soll alle 5 Minuten checken ob ein Update für eine
Modifikation rein kam. Danach die alten konvertierten Ordner löschen. Eine neue Konvertierung
starten, das ganze verpacken und danach einem zweiten Server (Linux) das "GO" zum Download
dieser gepackten Datei geben. Dort wird sie dann entpackt und zu ihrem Anwendungsort gebracht.
Soweit habe ich alles zur Hand. Auch unter dem Linux system wurde bereits alles vorbereitet.
Nun bin ich in Windows nicht so fit und weiß deshalb nicht was ich equivalent zu tail & grep
verwenden kann.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 309318
Url: https://administrator.de/forum/batch-ein-logfile-auf-aenderungen-pruefen-und-in-den-letzten-zeilen-nach-mehreren-bestimmten-eintraegen-309318.html
Ausgedruckt am: 20.04.2025 um 18:04 Uhr
6 Kommentare
Neuester Kommentar
Ich sitze übrigens für XCom2 an einer ähnlichen Sache ... ;)
Das funktioniert zwar, aber hat noch eine Macke
Edit: lasse ich nur als schlechtes Beispiel drin, da paßt auch noch was anderes nicht. loop3 muß aus loop2 raus, weil sonst mehrere Treffer angezeigt werden...
Das funktioniert zwar, aber hat noch eine Macke
@echo off
setlocal EnableDelayedExpansion
prompt -$G
set path=%windir%\system32;%path%
PushD "%~dp0"
if exist workshop_log.tmp del workshop_log.tmp
for /f "tokens=1 delims=" %%a in ('findstr /n "^" "workshop_log.txt"') do echo %%a>>"workshop_log.tmp"
for /f "tokens=1" %%b in ('findstr "^" "ModIDs.irgendwas"') do (
echo.
rem echo Schl1
set "iMod=%%b"
echo check Mod ID !iMod!
rem set "line="
for /f "tokens=1* delims=:" %%i in ('findstr !iMod! "workshop_log.tmp"') do (
rem echo Schl2
rem if not defined %%i echo nichts gefunden
echo %%j
set "line=%%i"
if not "!line!" == "" (
call :schl3
)
rem pause
)
rem pause
)
rem das hatte gehlt... ;)
goto End
:schl3
set /a "nline=%line%+1"
for /f " tokens=1* delims=:" %%I in ('findstr /b %nline% "workshop_log.tmp"') do (
echo %%J
rem pause
)
goto :eof
:End
pause
if exist workshop_log.tmp del workshop_log.tmp
PopD
endlocal
Edit: lasse ich nur als schlechtes Beispiel drin, da paßt auch noch was anderes nicht. loop3 muß aus loop2 raus, weil sonst mehrere Treffer angezeigt werden...
Es ist zum Auswachsen, das Skript sieht jetzt so aus:
(Fast) Alles was ich zur Fehlersuche eingebaut habe, hab ich drin gelassen.
Ich hab mir das wie folgt gedacht:
In der Theorie alles sehr schön soweit, aber mit dem Zeilensprung scheint etwas nicht zu klappen. Skip läst sich ja ohnehin nicht zu 0 setzen, aber anscheinen merkt der sich auch, wo er bei der letzen Suche etwas gefunden hat und nimmt das als Ausgangspunkt für skip. Wenn der Marker also etwa bei der Hälfte der Datei ist, dann macht der gar nix, weil er ja schon bis zum Ende springt - jedenfalls sieht es so aus...
Ich hatte skip dann auf 1 gesetzt, damit hat der offensichtlich eine Zeile nach dem MArker wieder angefangen (der Marker war auf Zeie 17, der erste Treffer auf 18, vor dem Marker gab es aber auch nochmal die gleichen Einträge).
Ist kein Marker drin, dann fängt der irgendwo an, er bringt jedenfalls nicht alle Ergebnisse.
Um das zu prüfen habe ich die Zeilen bei jeder Runde mit ausgeben lassen.
Ich bin jetzt mit meinem Latein am Ende
, vielleicht kann mir ja jemand sagen, was ich falsch mache? (Du benutzt Batch lasse ich nicht als Antwort gelten
)
Ach so, die Variablenbenennung hat eine Sinn: F=file, p=path, pF=path w/ file, o=original, t=tmp und b=bak...
Die ModID-Datei:
Die log-Datei mit mehreren Markern:
@echo off
cls
echo Start: Check for ARKMod updates in workshop_log.txt
echo. & echo.
setlocal EnableDelayedExpansion
prompt -$G
set path=%windir%\system32;%path%
PushD "%~dp0"
REM *************** Set Custom Vars *******************************************
set "Marker=last Merge"
REM *************** Set Custom File names **************************************
set "Fo_WSlog=workshop_log.txt"
set "Flo_modIDs=ModIDs.irgendwas"
REM *************** Set Custom Paths ******************************************
set "p_WS_Path=.\"
set "p_tmp_Path=.\"
:: ********** Timestamp for Backups **********
set test=0
set HOUR=%time:~0,2%
set dtStamp9=%date:~-2%-%date:~3,2%-%date:~0,2%_0%time:~1,1%%time:~3,2%
set dtStamp24=%date:~-2%-%date:~3,2%-%date:~0,2%_%time:~0,2%%time:~3,2%
if "%HOUR:~0,1%"=="" (
set dtStamp=%dtStamp9%
) else (
set dtStamp=%dtStamp24%
)
REM *************** Determine Derived Paths and File Names **************
set "Ft_WSlog=%Fo_WSlog%.tmp"
set "Fb_WSlog=%Fo_WSlog%.bak_%dtStamp%"
set "pFb_WSlog=%p_WS_Path%%Fb_WSlog%"
set "pFo_WSlog=%p_WS_Path%%Fo_WSlog%"
set "pFlo_modIDs=%p_WS_Path%%Flo_modIDs%"
set "pFt_WSlog=%p_tmp_Path%%Ft_WSlog%"
REM *************** Set Program Vars ***********************************
set /a "cnt_lp1=0"
set /a "skip_lp1=0"
set "bak_WSlog=n"
REM ********************Begin Processing ********************************
REM copy %pFo_WSlog% %pFb_WSlog%
REM echo %pFo_WSlog% %pFb_WSlog% & echo. & echo. & echo.
attrib +r %pFo_WSlog%
if exist %pFt_WSlog% del %pFt_WSlog%
for /f "tokens=1 delims=" %%a in ('findstr /n "^" "%pFo_WSlog%"') do echo %%a>>"%pFt_WSlog%"
echo WSPath : %p_WS_Path%
echo TmpPath: %p_tmp_Path%
echo ModIDs : %pFlo_modIDs%
echo OrgLog : %pFo_WSlog%
echo TempLog: %pFt_WSlog%
echo BakLog : %pFb_WSlog%
echo Marker : %Marker%
echo off
for /f "tokens=1 delims=:" %%m in ('findstr /i "%Marker%" "%pFt_WSlog%"') do (
REM echo m: _%%m_ n: _%%n_
if not "%%n"=="" set /a skip_lp1=%%m"
REM echo !skip_lp1! & echo. & echo.
)
for /f "tokens=1" %%b in ('findstr /i "^" "%pFlo_modIDs%"') do (
echo.
echo loop1
set "iMod=%%b"
echo check Mod ID !iMod!
set "i="
set "j="
REM echo on
echo _!skip_lp1!_
REM findstr !iMod! "%pFt_WSlog%"
REM set /a "cnt_lp2=0"
REM if not "!skip_lp1!"=="0" ( set "skip_lp2=1" ) else ()
for /f "tokens=1* delims=:" %%i in ('findstr /i !iMod! "%pFt_WSlog%"') do (
echo loop2
echo %%i
set "i=%%i"
set "j=%%j"
)
REM echo on
if not "!j!"=="" (
set "line=!i!"
echo !j!
set "bak_WSlog=y"
if not exist %pFb_WSlog% copy %pFo_WSlog% %pFb_WSlog%>nul
REM echo on
set /a "nline=!line!+1"
for /f " tokens=1* delims=:" %%I in ('findstr /i /b !nline! "%pFt_WSlog%"') do (
echo loop3
echo %%J
REM pause
)
)
)
pause>nul
echo %pFt_WSlog%
echo %pFo_WSlog%
echo bak %bak_WSlog%
REM echo on
rem del %pFt_WSlog%
if "%bak_WSlog%"=="y" (
if not exist %pFb_WSlog% (
echo ----------- Backup not found, abort... ---------------
pause
goto _End
) else (
attrib -r %pFo_WSlog% & del %pFo_WSlog%
pause
for /f " tokens=1,2* delims=:" %%C in ('findstr /i /n "^" "%pFt_WSlog%"') do (
echo %%C %%E
REM echo %%d
if "%%E"=="" (
echo.>>"%pFo_WSlog%"
) else (
if not "%%E"=="%Marker%" echo %%E>>"%pFo_WSlog%"
)
)
echo %Marker%>>"%pFo_WSlog%"
)
)
attrib -r %pFo_WSlog%
:_End
echo. & echo. & echo. & echo.
echo Completed: Check for ARKMod updates in workshop_log.txt
pause>nul
prompt $P$G
PopD
endlocal
(Fast) Alles was ich zur Fehlersuche eingebaut habe, hab ich drin gelassen.
Ich hab mir das wie folgt gedacht:
- Es ist ein Marker nötig, der anzeigt, wann das letzte Mal die Updates übertragen wurden, wenn danach noch etwas kommt, dann gab es Updates
- es muß auch funktionieren wenn aus irgendwelchen Gründen kein Marker (log gelöscht)
- oder mehrere Marker drin stehen (Prozess unterbrochen o.ä.)
- es darf nicht in die Datei geschrieben werden, wenn der Prozess läuft, daher Schreibschutz (ich hoffe Steam ignoriert den nicht...)
- Es wird eine tmp-Datei erstellt, welche die Zeilen nummeriert.
- In der tmp-Datei wird nach dem letzten Marker gesucht, für einen späteren Zeilen-Skip wird die Zeile als skip_lp1 gespeichert, i und j werden geleert - Schleife beendet
- loop1 geht eine Liste mit allen Mod-IDs (muß zusammengestellt werden) durch und prüft für jede, ob nach dem letzen Marker ein Update kam
- Dazu wird loop2 geöffnet mit skip=%skip_lp1%, die sucht nach der ModID ab der Zeile skip_lp1+1 und speichert bei jeder Runde die Zeilenzahl und den Text des Treffers, für den letzten Treffern werden die als i und j übernommen, und eine Prüfvariable fürs Backup zu y geändert und beim ersten mal das Backup erstellt - Schleife beendet
- wenn j (Mod-Update-Text) nicht leer ist, wird line=!i! gesetzt und nline=!line!+1 (Folgezeile für die 2. notwendige Ausgabe)
- mach dieser Zeile sucht der in loop3 und gibt den dazugehörigen Text aus - Schleife beendet
- loop1 - Schleife beendet
- hinten dran wird, wenn die Backupvariable y ist, die Log Datei gelöscht, aus der tmp-Datei wieder aufgebaut, wobei alle Marker gelöscht werden und ganz hinten wieder einer eingefügt wird
In der Theorie alles sehr schön soweit, aber mit dem Zeilensprung scheint etwas nicht zu klappen. Skip läst sich ja ohnehin nicht zu 0 setzen, aber anscheinen merkt der sich auch, wo er bei der letzen Suche etwas gefunden hat und nimmt das als Ausgangspunkt für skip. Wenn der Marker also etwa bei der Hälfte der Datei ist, dann macht der gar nix, weil er ja schon bis zum Ende springt - jedenfalls sieht es so aus...
Ich hatte skip dann auf 1 gesetzt, damit hat der offensichtlich eine Zeile nach dem MArker wieder angefangen (der Marker war auf Zeie 17, der erste Treffer auf 18, vor dem Marker gab es aber auch nochmal die gleichen Einträge).
Ist kein Marker drin, dann fängt der irgendwo an, er bringt jedenfalls nicht alle Ergebnisse.
Um das zu prüfen habe ich die Zeilen bei jeder Runde mit ausgeben lassen.
Ich bin jetzt mit meinem Latein am Ende
Ach so, die Variablenbenennung hat eine Sinn: F=file, p=path, pF=path w/ file, o=original, t=tmp und b=bak...
Die ModID-Datei:
12345
23456
34567
45678
56789
XXXXX
Die log-Datei mit mehreren Markern:
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item 12345 1
[AppID 346110] Finished Workshop download job : No Error (1)1
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item 23456 1
[AppID 346110] Finished Workshop download job : No Error (2)1
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
last Merge
[AppID 346110] Detected workshop change : changed cached item 45678
[AppID 346110] Finished Workshop download job : No Error (4)
[AppID 346110] Detected workshop change : changed cached item 12345 2
[AppID 346110] Finished Workshop download job : No Error (1)2
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item 12345 3
[AppID 346110] Finished Workshop download job : No Error (1)3
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
last Merge
[AppID 346110] Detected workshop change : changed cached item 23456 3
[AppID 346110] Finished Workshop download job : No Error (2)3
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
last Merge
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item XXXXXXXXX
[AppID 346110] Finished Workshop download job : No Error (x)
[AppID 346110] Detected workshop change : changed cached item 12345 4
[AppID 346110] Finished Workshop download job : No Error (1)4
[AppID 346110] Detected workshop change : changed cached item 56789 3
[AppID 346110] Finished Workshop download job : No Error (5)3
last Merge
Da steckt noch ein fehler drin, den ich nicht finde. Wenn Du Zeile 89 durch ersetzt, funktioniert es mit einem Marker, wie es geschrieben ist, ohne, die Variante, daß mehrere Marker auftauchen sollte nur im Fehlerfall auftreten - das habe ich auch noch nicht gelöst bekommen...
for /f "skip=1 tokens=1* delims=:" %%I in ('findstr /i /b !nline! "%pFt_WSlog%"') do (