anomalyx
Goto Top

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.

Content-Key: 309318

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

Ausgedruckt am: 19.03.2024 um 03:03 Uhr

Mitglied: Anomalyx
Anomalyx 08.07.2016 um 18:37:13 Uhr
Goto Top
Um das Vorhaben noch genauer zu erläutern. Es geht hier um
automatische Modupdates von ARK Servern die auf Linux laufen.
Leider gibt es keinen direkten Moddownload vom Spiel. Ich hätte
zwar die möglichkeit die Modifikationen per SteamCMD direkt auf
meinen Linux-Server zu ziehen. Allerdings müssen diese erst mit
Ionic.Zip konvertiert werden, so dass das Spiel die Modifikationen
überhaupt erst nutzen kann. Dazu kommt noch eine .mod
Datei die erstellt werden muss. Allerdings habe ich unter Linux keine
passenden hilfen und Anleitungen zur Ionic.Zip gefunden.

Ich habe dafür fertig Server scripts gefunden. Diese scheinen soetwas
per Perl zu realisieren. Allerdings möchte ich keine fertigsysteme nutzen.
Raus ziehen ging leider auch nicht so leicht, da es zu viele abhängigkeiten
gibt.

Deshalb habe ich nun den Windows VServer auf dem ich die Mods
downloade, konvertiere, verpacke und sie dann zum Linux Server schicke.
Mitglied: Ben.Blake.79
Ben.Blake.79 09.07.2016, aktualisiert am 10.07.2016 um 21:16:07 Uhr
Goto Top
Ich sitze übrigens für XCom2 an einer ähnlichen Sache ... ;)

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...
Mitglied: Ben.Blake.79
Ben.Blake.79 09.07.2016, aktualisiert am 10.07.2016 um 13:47:54 Uhr
Goto Top
Ich habe gerade gesehen, das macht noch nicht alles, was Du brauchst, ich bastle nochmal...
Mitglied: Ben.Blake.79
Ben.Blake.79 10.07.2016 aktualisiert um 21:29:31 Uhr
Goto Top
Es ist zum Auswachsen, das Skript sieht jetzt so aus:

@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 face-sad , vielleicht kann mir ja jemand sagen, was ich falsch mache? (Du benutzt Batch lasse ich nicht als Antwort gelten face-wink )

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
Mitglied: Anomalyx
Anomalyx 11.07.2016 um 09:52:19 Uhr
Goto Top
Richtig goil, dass du das der öffentlichkeit nicht vor enthällst. Danke dir, ich hoffe damit erreiche ich mein Ziel nun! face-smile
Mitglied: Ben.Blake.79
Ben.Blake.79 15.07.2016 um 09:12:12 Uhr
Goto Top
Da steckt noch ein fehler drin, den ich nicht finde. Wenn Du Zeile 89 durch
for /f "skip=1 tokens=1* delims=:" %%I in ('findstr /i /b !nline! "%pFt_WSlog%"') do (  
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...