Ausgelesene Zeile als echo verfügbar, bekomme sie aber nicht in eine Variable
Hallo erstmal an alle die das lesen,
ich bin im Batch schreiben blutiger Anfänger.
Ich möchte aus einer sehr großen (kann bis 200MB groß werden) txt Datei die letzte Zeile auslesen und weiter verarbeiten. Das Auslesen und auf dem Bildschirm ausgeben gelingt mir mit folgendermaßen:
FOR /F "skip=%ZN% delims=" %%i IN (C:\Windows\Temp\Work.txt) do echo %%i
Will ich dieses nun im Scribt einer Variable übergeben:
FOR /F "skip=%ZN% delims=XXX" %%i IN (C:\Windows\Temp\Work.txt) do Set ZT=%%i
oder
FOR /F "skip=%ZN% delims=XXX" %%i IN (C:\Windows\Temp\Work.txt) do "Set ZT=%%i"
bleibt die Variable leer.
Der Zeilenaufbau in der Datei sieht folgendermaßen aus:
m 16:50:35|main Speed 381.22 Mh/s gpu/0 31.77 gpu/1 31.77 gpu/2 31.77 gpu/3 31.77 gpu/4 31.77 gpu/5 31.77 gpu/6 31.77 gpu/7 31.92 gpu/8 31.62 gpu/9 31.77 gpu/10 31.77 gpu/11 31.77 [A6101+88:R7+2:F0] Time: 18:37
Bin für jeden Lösungsansatz dankbar
ich bin im Batch schreiben blutiger Anfänger.
Ich möchte aus einer sehr großen (kann bis 200MB groß werden) txt Datei die letzte Zeile auslesen und weiter verarbeiten. Das Auslesen und auf dem Bildschirm ausgeben gelingt mir mit folgendermaßen:
FOR /F "skip=%ZN% delims=" %%i IN (C:\Windows\Temp\Work.txt) do echo %%i
Will ich dieses nun im Scribt einer Variable übergeben:
FOR /F "skip=%ZN% delims=XXX" %%i IN (C:\Windows\Temp\Work.txt) do Set ZT=%%i
oder
FOR /F "skip=%ZN% delims=XXX" %%i IN (C:\Windows\Temp\Work.txt) do "Set ZT=%%i"
bleibt die Variable leer.
Der Zeilenaufbau in der Datei sieht folgendermaßen aus:
m 16:50:35|main Speed 381.22 Mh/s gpu/0 31.77 gpu/1 31.77 gpu/2 31.77 gpu/3 31.77 gpu/4 31.77 gpu/5 31.77 gpu/6 31.77 gpu/7 31.92 gpu/8 31.62 gpu/9 31.77 gpu/10 31.77 gpu/11 31.77 [A6101+88:R7+2:F0] Time: 18:37
Bin für jeden Lösungsansatz dankbar
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 367767
Url: https://administrator.de/forum/ausgelesene-zeile-als-echo-verfuegbar-bekomme-sie-aber-nicht-in-eine-variable-367767.html
Ausgedruckt am: 14.05.2025 um 15:05 Uhr
17 Kommentare
Neuester Kommentar
Hallo AmVerzweifeln,
wenn Du die Datei zeilenweise durchläufst, dann wird "echo" für jede Zeile ausgeführt.
Bei "set" ist es ebenso, allerdings wird die Variable jedesmal neu belegt und nur die letzte Belegung bleibt nach der Schleife bestehen.
Sollte die letzte Belegung einen leeren Wert zuordnen, so ist auch Deine Variable leer, respektive ungesetzt.
Schau mal was dabei raukommt.
Auf
Da fehlen wohl Infos deinerseits.
Gruß Frank
wenn Du die Datei zeilenweise durchläufst, dann wird "echo" für jede Zeile ausgeführt.
Bei "set" ist es ebenso, allerdings wird die Variable jedesmal neu belegt und nur die letzte Belegung bleibt nach der Schleife bestehen.
Sollte die letzte Belegung einen leeren Wert zuordnen, so ist auch Deine Variable leer, respektive ungesetzt.
FOR /F "skip=%ZN% delims=" %%i IN (C:\Windows\Temp\Work.txt) do
(
echo Wert: %%i
if not "%%i"=="" set ZT=%%i
)
echo ZT: %ZT%
Schau mal was dabei raukommt.
Auf
skip=%ZN%
und delims=XXX"
kann ich mir keinen Reim machen.Da fehlen wohl Infos deinerseits.
Gruß Frank
Hallo AmVerzweifeln,
mit
Bsp.:
Nimm mal
Damit das funktioniert musst Du es maskieren:
Tutorial zur FOR-Schleife
Gruß Frank
mit
|
verkettet man Befehle.Bsp.:
set ZA=16:51:43|main
Der Befehl "main" ist entweder falsch geschrieben oder konnte nicht gefunden werden.
Nimm mal
|
als Delimiter.Damit das funktioniert musst Du es maskieren:
delims=^|
Tutorial zur FOR-Schleife
Gruß Frank
Hallo AmVerzweifeln,
if würde hier nicht mit
Aus Deinen Beispielen geht allerdings nicht hervor wo Du eigentlich hinwillst und nur sehr dürftig wo Du eigentlich herkommst.
löscht die Variable.
Wirf mal hier einem Blick drauf:
Formatierungen in den Beiträgen
Gruß Frank
Zitat von @AmVerzweifeln:
Wenn ein anderer Buchstabe da steht, will ich die Zeile davor prüfen.
Mein Code funktioniert, wenn ich beim ersten Versuch auf ein m treffe. Wenn in der ersten Zeile ein i steht, ich die Zeile davor prüfe wo ein m steht erhalte ich immer noch das Ergebnis der ersten Zeile.
Wenn ein anderer Buchstabe da steht, will ich die Zeile davor prüfen.
Mein Code funktioniert, wenn ich beim ersten Versuch auf ein m treffe. Wenn in der ersten Zeile ein i steht, ich die Zeile davor prüfe wo ein m steht erhalte ich immer noch das Ergebnis der ersten Zeile.
Zitat von @AmVerzweifeln:
Ich lese die erste Zeile
Code FOR /F "tokens=1 skip=%ZN%" %%i IN (C:\Windows\Temp\Work.txt) do Set ZT=%%i
Prüfe ZT und wenn <> m sage ich per Goto, gehe zurück und prüfe die vorige Zeile (ZN-1)
Ich lese die erste Zeile
Code FOR /F "tokens=1 skip=%ZN%" %%i IN (C:\Windows\Temp\Work.txt) do Set ZT=%%i
Prüfe ZT und wenn <> m sage ich per Goto, gehe zurück und prüfe die vorige Zeile (ZN-1)
if würde hier nicht mit
goto
arbeiten, sondern den Vorzeilenwert und den aktuellen Wert speichern und entsprechnd agieren. FOR /F "tokens=1 skip=%ZN%" %%i IN (C:\Windows\Temp\Work.txt) do
(
set vorher=%ZT%
set ZT=%%i
if not "%ZT%"=="m" set ZT=%vorher%
)
Zitat von @AmVerzweifeln:
Gibt es so eine Art "Clear Befehl", welcher den Inhalt aus der ersten Prüfung löscht?
Gibt es so eine Art "Clear Befehl", welcher den Inhalt aus der ersten Prüfung löscht?
set Variable=
Wirf mal hier einem Blick drauf:
Formatierungen in den Beiträgen
Gruß Frank
Hallo AmVerzweifeln,
Wenn Dich nur die Zeilen interessieren, die mit "m " anfangen, dann solltest Du auch nur diese untersuchen, um nicht umständlich filtern zu müssen.
Diese Code könnte die Aufgabe lösen, falls Uhrzeit und Inhalt der letzen m-Zeile alles ist, was Dich interessiert.
Ein paar Worte dazu:
Das gibt alle Zeilen aus die mit "m " beginnen.
Die Ausgabe des Befehls wird in der For-Schleife zeilenweise ausgewertet.
Getrennt wird am
Genutzt wird Token 1 => %%f und der Rest (Token *) => %%g
Die Variablen werden solange erneut belegt, bis die letzte Zeile ausgewertet wurde.
Nach der For-Schleife kommt die Ausgabe, wobei die Zeit zuvor noch vom führenden "m " befreit wird.
Bei mir bleibt die Frager offen was Du mit der Zeilennummer willst.
Hat das Performancegründe und Du möchtest deshalb ein
Gruß Frank
Zitat von @AmVerzweifeln:
Aber vieleicht verenne ich mich bei der ganzen konzeptionierung in die falsche Richtung und das lässt sich alles viel einfacher lösen.
Aber vieleicht verenne ich mich bei der ganzen konzeptionierung in die falsche Richtung und das lässt sich alles viel einfacher lösen.
Wenn Dich nur die Zeilen interessieren, die mit "m " anfangen, dann solltest Du auch nur diese untersuchen, um nicht umständlich filtern zu müssen.
@echo off
for /f "tokens=1,* delims=^|" %%f in ('findstr /b "m " C:\Windows\Temp\Work.txt') do (
set zeilenzeit=%%f
set zeilentext=%%g
)
set zeilenzeit=%zeilenzeit:~2%
echo Um %zeilenzeit% Uhr wurde Folgendes ausgegeben: %zeilentext%
Ein paar Worte dazu:
findstr /b "m " C:\Windows\Temp\Work.txt
Die Ausgabe des Befehls wird in der For-Schleife zeilenweise ausgewertet.
Getrennt wird am
|
.Genutzt wird Token 1 => %%f und der Rest (Token *) => %%g
Die Variablen werden solange erneut belegt, bis die letzte Zeile ausgewertet wurde.
Nach der For-Schleife kommt die Ausgabe, wobei die Zeit zuvor noch vom führenden "m " befreit wird.
Bei mir bleibt die Frager offen was Du mit der Zeilennummer willst.
Hat das Performancegründe und Du möchtest deshalb ein
skip=Zeilenanzahl
nutzen oder benötigst Du die Zeilennummer in der Ausgabe?Gruß Frank
Hallo Franco,
Hier eine funktionierende Variante:
Mit Deiner (aktualisierten) Quelldatei...
<code type=plain"> m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
i 22:44:41|CUDA5 So
i 22:44:41|CUDA5 No
i 22:44:41|stratum Acc
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:42|main Sp
...kommt das hier raus:
Gruß Frank
PS: Wer ist Ralf?
Zitat von @AmVerzweifeln:
Der Code von dir gibt mir leider nur leere Variablen. Vor dem "m" bzw "i" sind drei Leerstellen.
wenn Du die Spielregel änderst...Der Code von dir gibt mir leider nur leere Variablen. Vor dem "m" bzw "i" sind drei Leerstellen.
Hier eine funktionierende Variante:
@echo off
for /f "tokens=1,* delims=^|" %%f in ('findstr /r /c:"^[ ][ ][ ]m[ ]" C:\Windows\Temp\Work.txt') do (
set zeilenzeit=%%f
set zeilentext=%%g
)
set zeilenzeit=%zeilenzeit:~5%
echo Um %zeilenzeit% Uhr wurde Folgendes ausgegeben: %zeilentext%
Mit Deiner (aktualisierten) Quelldatei...
<code type=plain"> m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
m 22:44:40|main Sp
i 22:44:41|CUDA5 So
i 22:44:41|CUDA5 No
i 22:44:41|stratum Acc
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:41|main Sp
m 22:44:42|main Sp
...kommt das hier raus:
Um 22:44:42 Uhr wurde Folgendes ausgegeben: main Sp
Gruß Frank
PS: Wer ist Ralf?
Hallo Franco,
ich habe mir mal eine "richtige" Testdatei erzeugt,
die 1.160.000 Zeilen hat und so aussieht:
Meine letzte Variante mit findstr funktioniert zwar, ist aber bei einer größeren Datei weit jenseits von performant.
Habe ich eine Testdatei mit 1.000 Zeilen geht es noch einigermaßen, aber bei 100.000 Zeilen dauert es schon 9 Minuten bis die Suche fertig ist.
Ich habe es jetzt mit skip und ohne findstr gemacht, also so, wie Du es im Grunde auch schon gemacht hast.
Das geht mit der großen Datei, auch auf meinem eher schwächeren Rechner, ausreichend performant.
Die Batch ermittelt mit Deiner Methode die Zeilenanzahl und skipt bei
Sollte die letzte Zeile schon ein Treffer sein, also eine Zeile vom Typ "m", dann dauert die Suche ca. 3 Sek.
Sollte die Zeile kein Treffer sein, so wird
So geht der
Das dauert knapp eine Sekunde pro Zeile.
Wenn Typ-m-Zeilen also keine Seltenheit sind, ist der Suchvorgang vermutlich schnell genug.
Damit verhindert man, dass man noch Werte vom vorhergehenden Durchlauf in den Variabel hat und eventuell diese angezeigt bekommt und nicht versteht wo die bloß herkommen.
Gruß Frank
ich habe mir mal eine "richtige" Testdatei erzeugt,
die 1.160.000 Zeilen hat und so aussieht:
m 16:50:35|main Speed 381.22 Mh/s gpu/0 31.77 gpu/1 31.77 gpu/2 31.77 gpu/3 31.77 gpu/4 31.77 gpu/5 31.77 gpu/6 31.77 gpu/7 31.92 gpu/8 31.62 gpu/9 31.77 gpu/10 31.77 gpu/11 31.77 [A6101+88:R7+2:F0] Time: 18:37
...
m 16:50:35|main Speed 381.22 Mh/s gpu/0 31.77 gpu/1 31.77 gpu/2 31.77 gpu/3 31.77 gpu/4 31.77 gpu/5 31.77 gpu/6 31.77 gpu/7 31.92 gpu/8 31.62 gpu/9 31.77 gpu/10 31.77 gpu/11 31.77 [A6101+88:R7+2:F0] Time: 18:37
Meine letzte Variante mit findstr funktioniert zwar, ist aber bei einer größeren Datei weit jenseits von performant.
Habe ich eine Testdatei mit 1.000 Zeilen geht es noch einigermaßen, aber bei 100.000 Zeilen dauert es schon 9 Minuten bis die Suche fertig ist.
Ich habe es jetzt mit skip und ohne findstr gemacht, also so, wie Du es im Grunde auch schon gemacht hast.
Das geht mit der großen Datei, auch auf meinem eher schwächeren Rechner, ausreichend performant.
@echo off
:config
set suchpfad=C:\Windows\Temp
set suchdatei=Work.txt
:alte_werte_loeschen
set zeilenanzahl=
set zeilenskip=
set zeilenanfang=
set zeilentyp=
set zeilenzeit=
set zeilentext=
set ausgabezeile=
:zeilenanzahl_ermitteln
find %suchpfad%\%suchdatei% /c /v "" > %suchpfad%\zeilenanzahl.txt
for /f "tokens=3" %%i in (%suchpfad%\zeilenanzahl.txt) do (
set /a zeilenanzahl=%%i
)
REM echo Zeilenanzahl: %zeilenanzahl%
set /a zeilenskip=%zeilenanzahl%
:suchloop
set /a zeilenskip=%zeilenskip%-1
if %zeilenskip% lss 1 goto ende
call :zeile_untersuchen %zeilenskip%
set zeilentyp=%zeilenanfang:~3,1%
set zeilenzeit=%zeilenanfang:~5%
REM echo Zeilentyp : %zeilentyp%
REM echo Zeilenzeit: %zeilenzeit%
REM echo Zeilentext: %zeilentext%
if not "%zeilentyp%"=="m" goto suchloop
:ausgabe
set /a ausgabezeile=%zeilenskip%+1
echo Zeile: %ausgabezeile%
echo Zeit : %zeilenzeit% Uhr
echo Text : %zeilentext%
:aufraeumen
set zeilenanzahl=
set zeilenskip=
set zeilenanfang=
set zeilentyp=
set zeilenzeit=
set zeilentext=
set ausgabezeile=
if exist %suchpfad%\zeilenanzahl.txt del %suchpfad%\zeilenanzahl.txt
:ende
exit /b
REM *** Hier endet die Batch, es folgt noch eine Funktion ***
:zeile_untersuchen
REM echo Ueberspringe %1 Zeilen
for /f "skip=%1 tokens=1,* delims=^|" %%f in (%suchpfad%\%suchdatei%) do (
set zeilenanfang=%%f
set zeilentext=%%g
exit /b
)
Die Batch ermittelt mit Deiner Methode die Zeilenanzahl und skipt bei
zeile_untersuchen
zur letzen Zeile.Sollte die letzte Zeile schon ein Treffer sein, also eine Zeile vom Typ "m", dann dauert die Suche ca. 3 Sek.
Sollte die Zeile kein Treffer sein, so wird
zeile_untersuchen
erneut aufgerufen, aber mit einem skip weniger.So geht der
suchloop
immer eine Zeile höher, bis ein Treffer erzielt wurde.Das dauert knapp eine Sekunde pro Zeile.
Wenn Typ-m-Zeilen also keine Seltenheit sind, ist der Suchvorgang vermutlich schnell genug.
alte_werte_loeschen
und aufraeumen
sind eigentlich nur relevant, wenn man die Batch manuell und wiederholt in derselben Eingabeaufforderung ausführt.Damit verhindert man, dass man noch Werte vom vorhergehenden Durchlauf in den Variabel hat und eventuell diese angezeigt bekommt und nicht versteht wo die bloß herkommen.
Gruß Frank
Hallo Franco,
...dann hast Du die Spielregel wieder geändert,
Aber egal, wenn's bei Dir jetzt läuft ist alles gut.
Ob Logdateien wirklich 1,16 Millionen Zeilen haben müssen, wäre noch eine andere Frage.
Man könnte sie sicher auch gelegentlich wegspeichern und neu (leer) anlegen.
Gruß Frank
Zitat von @AmVerzweifeln:
...in
geändert, und siehe da: Funktioniert einwandfrei.
...in
set zeilentyp=%zeilenanfang:~2,1%
...dann hast Du die Spielregel wieder geändert,
Vor dem "m" bzw "i" sind drei Leerstellen
denn mit drei Leerzeichen müsste es mit ~3,1
funktionieren.Aber egal, wenn's bei Dir jetzt läuft ist alles gut.
Ob Logdateien wirklich 1,16 Millionen Zeilen haben müssen, wäre noch eine andere Frage.
Man könnte sie sicher auch gelegentlich wegspeichern und neu (leer) anlegen.
Gruß Frank