Per Batch unbekannte Inhalte an variablen Stellen aus Textdatei auslesen und in neue Textdatei einfügen
Servus zusammen,
habe schon verschidenes mit "for" und "findstr" versucht, doch die Ergebnisse waren leider nicht brauchbar.
Vielleicht weiß jemand von euch eine Lösung?
In einer Logdatei sind ausschließlich fehlerhafte Anmeldeversuche von Benutzern enthalten.
Die Logdatei ist leider extrem unübersichtlich und groß.
Alles was ich herausfiltern möchte, ist das DATUM und der BENUTZERNAME, der versucht wurde.
Hier mal eine vereinfachte Variante des Szenarios:
Inhalt von Logdatei.txt:
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM1
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME1 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM2
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME2 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM3
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME3 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM4
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME4 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM5
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME5 unbekanntesWort unbekanntesWort
usw
Ziel Inhalt von Ergebnisdatei.txt soll sein:
DATUM1 unbekannterBENUTZERNAME1
DATUM2 unbekannterBENUTZERNAME2
DATUM3 unbekannterBENUTZERNAME3
DATUM4 unbekannterBENUTZERNAME4
DATUM5 unbekannterBENUTZERNAME5
Bin für jede Anregung dankbar.
habe schon verschidenes mit "for" und "findstr" versucht, doch die Ergebnisse waren leider nicht brauchbar.
Vielleicht weiß jemand von euch eine Lösung?
In einer Logdatei sind ausschließlich fehlerhafte Anmeldeversuche von Benutzern enthalten.
Die Logdatei ist leider extrem unübersichtlich und groß.
Alles was ich herausfiltern möchte, ist das DATUM und der BENUTZERNAME, der versucht wurde.
Hier mal eine vereinfachte Variante des Szenarios:
Inhalt von Logdatei.txt:
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM1
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME1 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM2
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME2 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM3
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME3 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM4
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME4 unbekanntesWort unbekanntesWort
irgendeineZeile unbekanntesWort
irgendeineZeile Datum: DATUM5
irgendeineZeile unbekanntesWort
irgendeineSerLangeZeile unbekanntesWort unbekanntesWort unbekanntesWort Benutzername: unbekannterBENUTZERNAME5 unbekanntesWort unbekanntesWort
usw
Ziel Inhalt von Ergebnisdatei.txt soll sein:
DATUM1 unbekannterBENUTZERNAME1
DATUM2 unbekannterBENUTZERNAME2
DATUM3 unbekannterBENUTZERNAME3
DATUM4 unbekannterBENUTZERNAME4
DATUM5 unbekannterBENUTZERNAME5
Bin für jede Anregung dankbar.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 170478
Url: https://administrator.de/contentid/170478
Ausgedruckt am: 23.11.2024 um 04:11 Uhr
3 Kommentare
Neuester Kommentar
Hallo PeterCoffee und willkommen im Forum!
Obwohl ich nicht davon ausgehe, dass es innerhalb der jeweiligen Zeilen keine gleichbleibende Struktur gäbe (und daher zB der Benutzername als 6. Wort in der Zeile steht), ein Ansatz, der jeweils das Wort nach dem ersten "Datum:" (in genau dieser Schreibweise inkl Beachtung der Groß-/Kleinschreibung) einer Zeile als Datum und das Wort nach dem ersten "Benutzername:" als Benutzernamen interpretiert, wobei das jeweils letzte vor dem Benutzernamen gefundene Datum diesem zugeordnet wird. Als Trennzeichen zwischen den Wörtern habe ich Deinem Beispiel entsprechend das Leerzeichen interpretiert:
Grüße
bastla
Obwohl ich nicht davon ausgehe, dass es innerhalb der jeweiligen Zeilen keine gleichbleibende Struktur gäbe (und daher zB der Benutzername als 6. Wort in der Zeile steht), ein Ansatz, der jeweils das Wort nach dem ersten "Datum:" (in genau dieser Schreibweise inkl Beachtung der Groß-/Kleinschreibung) einer Zeile als Datum und das Wort nach dem ersten "Benutzername:" als Benutzernamen interpretiert, wobei das jeweils letzte vor dem Benutzernamen gefundene Datum diesem zugeordnet wird. Als Trennzeichen zwischen den Wörtern habe ich Deinem Beispiel entsprechend das Leerzeichen interpretiert:
@echo off & setlocal
set "Ein=D:\Logdatei.txt"
set "Aus=D:\Ergebnisdatei.txt"
del "%Aus%" 2>nul
for /f "delims=" %%i in ('findstr "Datum: Benutzername:" "%Ein%"') do call :ProcessLine "%%i"
goto :eof
:ProcessLine
set "Gefunden=" & set "Wert="
for %%a in (%~1) do (
if not defined Gefunden (
if "%%a"=="Datum:" set "Gefunden=Datum"
if "%%a"=="Benutzername:" set "Gefunden=Benutzername"
) else (
if not defined Wert set "Wert=%%a"
)
)
if defined Wert set "%Gefunden%=%Wert%"
if defined Benutzername (
>>"%Aus%" echo %Datum% %Benutzername%
set "Datum=" & set "Benutzername="
)
goto :eof
bastla
Hallo PeterCoffee!
Auf speziellen Wunsch :
Bei weiteren Fragen: fragen
Nicht ganz leicht lesbar, aber ein weiterer Weg, den Ablauf nachzuvollziehen: Die Logdatei auf die ersten 5 Zeilen des Beispiels oben verkürzen, aus dem "
Die Inhalte von %%a sind hier in den Zeilen 13, 18 und 23 nachvollziehbar und in Zeile 25 (%Gefunden% hat inzwischen einen Wert, ist also nicht mehr "not defined", sodass der "else"-Zweig ausgeführt wird) erfolgt dann die Zuweisung an die Variable %Datum% (Erfolg siehe Zeile 28) ...
Grüße
bastla
P.S.: Mit meinem (fortgeschrittenen) Alter komme ich gut zurecht ...
Auf speziellen Wunsch :
@echo off & setlocal
set "Ein=D:\Logdatei.txt"
set "Aus=D:\Ergebnisdatei.txt"
del "%Aus%" 2>nul
REM Alle Zeilen mit den gesuchten Begriffen "Datum:" und "Benutzername:" ausfiltern und jeweils
REM an das Verarbeitungsunterprogramm als Parameter übergeben
for /f "delims=" %%i in ('findstr "Datum: Benutzername:" "%Ein%"') do call :ProcessLine "%%i"
REM Ende Hauptprogramm (damit Unterprogramm nicht nochmals durchlaufen wird)
goto :eof
:ProcessLine
REM Schalter rücksetzen = (Inhalte der) Variablen löschen
set "Gefunden=" & set "Wert="
REM Schleife über alle "Worte" der Zeile (=Parameter %1);
REM mit %~1 werden die umgebenden Anführungezeichen entfernt,
REM sodass anhand der Leerzeichen zerlegt werden kann
for %%a in (%~1) do (
REM Wurde in dieser Zeile noch kein Suchbegriff gefunden?
if not defined Gefunden (
REM Wenn aktuelles Wort ein Suchbegriff ist,
REM Art des Begriffes in der Variablen %Gefunden% speichern;
if "%%a"=="Datum:" set "Gefunden=Datum"
if "%%a"=="Benutzername:" set "Gefunden=Benutzername"
REM ansonsten dieses Wort ignorieren
) else (
REM Es wurde ein Suchbegriff gefunden, daher jetzt den
REM zugehörigen Wert speichern; dies aber nur für das
REM nächste Wort (und nicht für alle weiteren der Zeile) -
REM deshalb die Abfrage, ob der Wert bereits vorhanden ist
if not defined Wert set "Wert=%%a"
)
)
REM Wenn ein ein Wert gefunden wurde, kann er der passenden
REM Variablen (Name lt %Gefunden%) zugewiesen werden
if defined Wert set "%Gefunden%=%Wert%"
REM Wenn ein Benutzername gefunden wurde
REM (ganz exakt wäre es, auch das Vorhandensein
REM (des Datums zu kontrollieren),
if defined Benutzername (
REM Ausgabe durchführen und
>>"%Aus%" echo %Datum% %Benutzername%
REM Werte des Datensatzes wieder löschen
set "Datum=" & set "Benutzername="
)
REM Rücksprung ins Hauptprogramm
goto :eof
Nicht ganz leicht lesbar, aber ein weiterer Weg, den Ablauf nachzuvollziehen: Die Logdatei auf die ersten 5 Zeilen des Beispiels oben verkürzen, aus dem "
echo off
" ein "echo on
" machen und den Batch aus einer geöffneten CMD-Shell aufrufen - für die Logzeile 2 ergäbe das dann zBD:\TEMP>call :ProcessLine "irgendeineZeile Datum: DATUM1"
D:\TEMP>set "Gefunden=" & set "Wert="
D:\TEMP>for %a in (irgendeineZeile Datum: DATUM1) do (if not defined Gefunden (
if "%a" == "Datum:" set "Gefunden=Datum"
if "%a" == "Benutzername:" set "Gefunden=Benutzername"
) else (if not defined Wert set "Wert=%a" ) )
D:\TEMP>(if not defined Gefunden (
if "irgendeineZeile" == "Datum:" set "Gefunden=Datum"
if "irgendeineZeile" == "Benutzername:" set "Gefunden=Benutzername"
) else (if not defined Wert set "Wert=irgendeineZeile" ) )
D:\TEMP>(if not defined Gefunden (
if "Datum:" == "Datum:" set "Gefunden=Datum"
if "Datum:" == "Benutzername:" set "Gefunden=Benutzername"
) else (if not defined Wert set "Wert=Datum:" ) )
D:\TEMP>(if not defined Gefunden (
if "DATUM1" == "Datum:" set "Gefunden=Datum"
if "DATUM1" == "Benutzername:" set "Gefunden=Benutzername"
) else (if not defined Wert set "Wert=DATUM1" ) )
D:\TEMP>if defined Wert set "Datum=DATUM1"
D:\TEMP>if defined Benutzername (
echo DATUM1 1>>"Ergebnisdatei.txt"
set "Datum=" & set "Benutzername="
)
D:\TEMP>goto :eof
Grüße
bastla
P.S.: Mit meinem (fortgeschrittenen) Alter komme ich gut zurecht ...