trainee07
Goto Top

Batch mit mehrfachem Aufruf eines Perlscripts für jede Datei in einem Verzeichnis

und zwar mit Dateiabhängigen Übergabeargumenten

Hallo,

Ich habe folgende Situation:

Ordnerstruktur:

#Logauswertung (hier liegt die Batch Datei und das Perlscript)
-- #Logfiles (hier liegen die Logfiles, die wenn vorhanden alle nacheinander mit dem Perlscript bearbeitet werden sollen)
-- #Gescannte Logfiles (hier landen die Ausgabedateien des Perlscripts)

In meiner Batch lässt sich bis jetzt der Inhalt des Ordners "Logfiles" anzeigen wobei alle darin liegenden Dateien Dateinamen haben wie: 2007-10-30__1358.log.
Unter einem weiteren Menüpunkt lässt sich nun die vierstellige Nummer des Logfiles eingeben und daraufhin wird das Perlscript aufgerufen, jedoch mit dem Kompletten Dateinamen als erstes Übergabeargument und nochmal nur die Nummer als zweites Übergabeargument.
Den Vollständigen Dateinamen brauch ich um ihn dann im Perlscript als infile angeben zu können, die Nummer verwende ich um die Ausgabe Datei des Perlscripts dann passend zu benennen.

Also wie gesagt, mit Auswahl funktioniert das ganze jetzt schon und zwar so:

:prg21
	set /p lognr="Bitte vierstellige Logfilenummer eingeben: "  
	cd Logfiles
	if exist *%lognr%.log goto logistda
		echo.
		echo Logfile %lognr% nicht gefunden!
		cd..
		pause
	        goto ENDE21 
				
	:logistda 
		echo.
		echo Logfile %lognr% vorhanden
		cd..
		echo %LINE%
		cd Logfiles
		for /F %%i in ('dir /b /A:-d /o:n "*%lognr%.log"') do Set "logf=%%i"  
		cd..
		echo Aufruf von scanlog.pl mit der Datei %logf%
		echo %LINE%
		perl scanlog.pl %logf% %lognr%
		echo %LINE%
		set lognr=NUL1
		set logf=NUL2
	pause
:ENDE21 


Jetzt möchte ich noch einen Menüpunkt einfügen "Alle im Verzeichnis vorhandene Logfiles scannen", weiss jedoch nicht wie ich das realisieren soll.
-Verzeichnis auf Vorhandensein prüfen
-Verzeichnis auf Logfiles prüfen
-Jedes Logfile mit komplettem Dateinamen und Logfilenummer als Übergabeargumente mit dem Perlscript aufrufen.

Ich will noch erwähnen, dass es meine erste Batchdatei ist die ich programmiere aber diese Seite hier hat mir bei meinem bisherigen Weg schon sehr geholfen. face-smile

Also ich bin schon sehr gespannt auf die Lösung eines Profis ^^

Gruß
Trainee07

Content-Key: 72593

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

Printed on: April 18, 2024 at 22:04 o'clock

Member: Biber
Biber Nov 02, 2007 at 17:51:20 (UTC)
Goto Top
Moin Trainee07,

willkommen im Forum.

Um ein bisschen den Wiedererkennungswert der Batchdatei zu erhalten, habe ich nur ein paar kosmetische Änderungen gemacht.

@echo off & setlocal
Set "myRoot=X:\Logauswertung"  
Set "LogDir=%myRoot%\Logfile"  
Set "SumDir=%myRoot%\Gescannte Logfiles"  

:prg21

	set /p lognr="Bitte vierstellige Logfilenummer eingeben /leer für alle: "  
	if exist "%LogDir%\*%lognr%.log" goto logistda  
		echo.
		echo Logfile %lognr% nicht gefunden!
		pause
	        goto ENDE21 
				
	:logistda 
		echo.
		echo Logfile %lognr% vorhanden
		for /F %%i in ('dir /b /A:-d /o:n "%LogDir%\*%lognr%.log"') do Call :ProcWpl "%%~i"  
         goto :Ende21

:ProcWpl
for /f "tokens=2 delims=_" %i in ("%~n1") do Set lognr=%%i  
		echo Aufruf von scanlog.pl mit der Datei %1
REM ??		echo %LINE%
                                PushDir "%SumDir%    
		perl scanlog.pl %~1 %lognr%
		PopD
		Goto :eof
:::~~~~~~~ Ende des Call-Blocks "ProcWpl" ("Process with Perl")		 
REM ??		echo %LINE%
REM ??		set lognr=NUL1
REM ??		set logf=NUL2

	pause
:ENDE21 

wobei sich einige (bzw. die meisten) Anpassungen gar nicht auf Deine eigentliche Frage beziehen. Und zwar:
  • die ganzen Verzeichnisnamen sollten in Variablen. Eine Stelle zum Anpassen.
  • diese Verzeichniswechselei mit "cd runter" und "cd .." ist unnötig und erschwert die Fehlersuche

Ansonsten hab ich mich auf den Standpunkt gestellt:
  • entweder der verehrte User will und weiß eine %lognr%, dann läufts wie bisher
  • oder er weiß oder will keine einzelne, sondern alle.
  • Im zweiten Fall wird die %lognr% ermittelt.
  • Okay, im ersten Fall unnötigerweise auch. Aber Bätche jammern ja nicht rum.

Ist ungetestet, aber mal ein Anfang.

Grüße
Biber
Member: Trainee07
Trainee07 Nov 02, 2007 at 20:06:07 (UTC)
Goto Top
Hallo Biber,
vielen Dank für die schnelle Antwort, ich habe deinen Vorschlag direkt umgesetzt und muss zugeben dass mir das mit den cd.. Zeilen auch nicht gefallen hat.
Auch hat allein dein Vorschlag dazu geführt, dass ich ungefähr nur noch etwas mehr als die hälfte an code habe wie vorher ^^
Hatte natürlich für die Option "alle Logfiles scannen" eine eigene fast identische Funktion schreiben wollen *stirnklatscher*

Wichtig war mir jedenfalls, dass ich den Ordner "Logauswertung mit all seinem Inhalt überall hinkopieren kann, bzw auch auf andere Rechner und das Script läuft, vorausgesetzt man hat Activeperl vorher installiert.
Deswegen habe ich mit set "myRoot=%~dp0" gearbeitet. Und mit Hilfe einiger Anführungszeichen funktioniert "dir" jetzt auch mit Pfaden deren Ordnernamen Leerzeichen enthalten. face-smile

Nur leider funktioniert das mit /leer für alle Dateien nicht:
Er nimmt dann das Logfile der letzten Runde, scannt das auch wobei die Meldung
"Der Befehl Pushdir ist entweder falsch geschrieben oder konnte nicht gefunden werden" erscheint.
Vielleicht könntest du die Zeile mit Pushdir und
for /f "tokens=2 delims=_" %%i in ("%~n1") do Set lognr=%%i
auch noch ein bisschen näher erläutern ?

Wobei eigentlich der Ordner "Gescannte Logfiles" nur im Perlscript verwendet wird um halt da die Ausgabedateien abzulegen.


Hier nochmal Version 1.3 der Batch:

[code]
@echo off
setlocal
rem ======================================================================
::
:: ScanLOG V1.3
::
rem ----------------------------------------------------------------------
:: History
:: V1.0 - 2007-11-01 menü erstellt, scannt ausgewählte logfiles
:: V1.3 - 2007-11-02 fragt settings ab, scannt komplettes logverzeichnis
rem ======================================================================

rem ----------------------------------------------------------------------
:: CONFIG
rem ----------------------------------------------------------------------
cls
set sTitle=ScanLOG V1.3
set LINE=-------------------------------------------------------------------

set "myRoot=%~dp0"
set "LogDir=%myRoot%Logfiles"
set "sumdir=%myRoot%Gescannte Logfiles"

rem ----------------------------------------------------------------------
:: MAIN
rem ----------------------------------------------------------------------
:menue
echo %LINE%
echo.
echo %sTitle%
echo.
echo %LINE%
echo.
echo.
echo 1 - Liste vorhandener Logfiles anzeigen
echo 2 - Logfile(s) scannen
echo 3 - Gescannte Logfile(s) plotten [beta]
echo 0 - Raus hier
echo.
echo.
set %AuswahlEingabe%=
set /p AuswahlEingabe=Eingabe:
if %AuswahlEingabe% equ 1 goto prg1
if %AuswahlEingabe% equ 2 goto prg2
if %AuswahlEingabe% equ 3 goto prg3
if %AuswahlEingabe% equ 0 goto exit
goto menue
rem ----------------------------------------------------------------------
:prg1
cls
dir "%LogDir%" /b /o
pause
cls
goto menue
rem ----------------------------------------------------------------------
:prg2
:menue2
cls
echo.
echo %LINE%
dir "%LogDir%" /b /o
echo %LINE%
echo 1 - Logfile(s) scannen
echo 2 - ???
echo 0 - zurueck
echo.
echo.
set /p AuswahlEingabe=Eingabe:
if %AuswahlEingabe% equ 1 goto prg21
if %AuswahlEingabe% equ 2 goto prg22
if %AuswahlEingabe% equ 0 goto menue
goto menue2
rem ----------------------------------------------------------------------
:prg21
set /p lognr="Bitte vierstellige Logfilenummer eingeben oder /leer fuer alle: "
if exist "%LogDir%\*%lognr%.log" goto worklog
echo.
echo Logfile %lognr% nicht gefunden!
pause
goto prg2

:worklog
echo.
echo Logfile %lognr% vorhanden
for /f %%i in ('dir /b /A:-d /o:n "%LogDir%\*%lognr%.log"') do Call :ProcWpl "%%~i"
goto prg2

:ProcWpl
for /f "tokens=2 delims=_" %%i in ("%~n1") do Set lognr=%%i
echo Aufruf von scanlog.pl mit der Datei %1
echo %LINE%
PushDir "%SumDir%
perl scanlog.pl %~1 %lognr%
PopD
echo %LINE%
pause
cls
goto menue
REM ?? set lognr=NUL1
REM ?? set logf=NUL2
rem ----------------------------------------------------------------------
:prg3
echo.

:setup
echo Bitte auswaehlen:
set /p sys="Censored Konfig [1], Censored Konfig [2]: "
if %sys% equ 1 goto sys1
if %sys% equ 2 goto sys2
echo Eingabe ungültig
pause
goto prg3

:sys1
echo k1 > settings.txt
goto tol

:sys2
echo k2 > settings.txt

:tol
set /p tol="Anzahl tolerierter "40"-errors? "
echo t%tol% >>settings.txt
echo %LINE%
echo Scilab wird gestartet
echo Im aktiven Codefenster von plot.sce STRG+L druecken um zu plotten
pause
plot.sce
echo %LINE%
pause
cls
goto menue

:exit
goto END
endlocal

rem ----------------------------------------------------------------------
:: the end of all
rem ----------------------------------------------------------------------
:END
echo %LINE%
rem echo %0 was terminated.
echo press any key...
pause >nul

rem ======================================================================
:: EOF
rem ======================================================================
[/code]
Member: Biber
Biber Nov 02, 2007 at 23:35:05 (UTC)
Goto Top
Moin Trainee07,

ist mir heute abend auch zu spät, mich noch ernsthaft damit zu befassen.... morgen wieder.
Nur kurz:
"Der Befehl Pushdir ist entweder falsch geschrieben oder konnte nicht gefunden werden" erscheint.
Jepp, da hat M$ recht und ich unrechtt. Der Befehl heißt auch "PushD" ( und sein Partner "PopD").
Siehe Hilfe "PopD /?" bzw "PushD /?" am CMD-Prompt.

Vielleicht könntest du die Zeile mit Pushdir und
for /f "tokens=2 delims=_" %%i in ("%~n1") do Set lognr=%%i
Ja. Heißt übersetzt:

For /F .... %%i in ({irgendeinText}) Do ....
->lese den Text in der Klammer wie eine Textdatei ("/F" = wie ein File)

"tokens=2 delims=_"
-> nimm nur das zweite Token ("Teil" der Zeile), und zwar das zweite "Token", wenn Teile jeweils durch Zeichen "_" getrennt sind

"%~n1"
Und das ist der Text, der zerlegt werden soll.
Der %1 (Parameter 1), um den es hier geht, ist z.B. "D:\Logfiles\2007-11-01_1234.log".
Vom "ganzen" Parameter1 nur den Dateinamen %~n1 (ohne Extension) ist --> "2007-11-01_1234".
Das in Teile getrennt mit "Delims=_" ergibt :
Erstes Token "2007-11-01".
Zweites Token: "1234".

Soweit für heute.
Biber
Member: bastla
bastla Nov 03, 2007 at 08:13:54 (UTC)
Goto Top
Hallo Trainee07!

Als kurze Anmerkung zu
Nur leider funktioniert das mit /leer für alle Dateien nicht:
Er nimmt dann das Logfile der letzten Runde ...
Wenn Du vor der Eingabe ("set /p lognr= ...") die Variable löschst, wird nicht mehr der vorige Wert verwendet - die Zeile dafür:
set lognr=
Das solltest Du eigentlich mit allen einzugebenden ("set /p") Variablen so machen, wenn der entsprechende Programmteil mehrmals durchlaufen werden kann/soll.

Grüße
bastla
Member: Biber
Biber Nov 05, 2007 at 21:03:35 (UTC)
Goto Top
Moin Trainee07,

zu bastlas Hinweis kann ich auch nur wenig ergänzen.... mit dieser Strategie sollte es laufen.

Zusätzlich (und der Code-Sauberkeit wegen) sollten eigentlich die Zeilen..
:ProcWpl
for /f "tokens=2 delims=_" %%i in ("%~n1") do Set lognr=%%i  
geändert werden in ...
:ProcWpl
for /f "tokens=2 delims=_" %%i in ("%~n1") do Set einejanzprivateVariable=%%i  
....

Denn diese aus dem Dateinamen herausgepuhlte LfdNr wird zwar als Variable gebraucht, aber wirklich ja nur in diesem ":ProcWpl"-Block.

Die %lognr% außerhalb dieses Blocks hat eigentlich gar nichts damit zu tun.

Gib Bitte mal Feedback, ob ich mich halbwegs verständlich ausdrücken konnte, oder ob wir noch zusammen eine final version hier gemeinsam zusammenbraten wollen.

Grüße
Biber
Member: Biber
Biber Nov 14, 2007 at 21:55:25 (UTC)
Goto Top
Trainee07??
Bist Du noch bei uns?

Besorgt
Biber