didie08
Goto Top

Findstr in for schleife gibt kein errorlevel zurück

Hallo,

Ich möchte innerhalb einer for schleife den findstr Befehl nutzen. Ich habe hier das Problem das findstr immer %errorlevel%= 0 ausgibt, egal ob der gesuchte string in text2.txt vorkommt oder nicht.

@echo on & enabledelayedexpansion

for /f "tokens=1,2,3,4 delims= " %%i in ('findstr "name" text1.txt') do (  
	findstr "%%j" text2.txt  
	if %errorlevel% EQU 0 echo  %%i %%j %%k %%l>>text2.txt
)

Kann mir jemand weiterhefen ?

Content-ID: 134937

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

Ausgedruckt am: 22.11.2024 um 19:11 Uhr

Biber
Biber 02.02.2010 um 11:36:06 Uhr
Goto Top
Moin didie08,

ersetze das "if %errorlevel% EQU 0 echo " innerhalb der FOR-Anweisung durch ein "if NOT ERRORLEVEL 1 echo "

Erläuterung:
wenn du innerhalb einer Befehlszeile (und auch eine mehrzeilig formatierte FOR-Anweisung ist eine Befehlszeile) eine %variable% ansprichst,
so wie du in deinem Beispiel %errorlevel%, dann wird si einmal aufgelöst (quasi zu Beginn der Ausführung) und nicht dynamisch.

Grüße
Biber
edepfau
edepfau 02.02.2010 um 12:05:37 Uhr
Goto Top
(nur falls das jemand mal per google findet) - die Lösung ist richtig, aber die Erklärung trifft's nicht.

Wenn Du %errorlevel% benutzt, dann wird damit eine Umgebungsvariable namens errorlevel gemeint. Die gibt es in der Regel aber nicht!
Was Du wirklich meinst, ist der Rückgabewert ERRORLEVEL. Der wird wie in der Lösung per "IF ERRORLEVEL wert" abgefragt.
Noch fataler wird es, wenn man vorsichtshalber vor dem überwachten Befehl den ERRORLEVEL zurücksetzen will:
(FALSCH)
set /a %errorlevel%=0
Befehl
if %errorlevel% EQU 0 ....wird immer ausgeführt!

(RICHTIG)
verify >nul
if not errorlevel 1 ...


Noch eine Falle:
Bei IF ERRORLEVEL wird auf "grösser gleich wert" geprüft, nicht auf Gleichheit. Daher die Negation: "NOT >=" bedeutet "<". Der Grund ist, dass ein Rückgabewert von 0 OK bedeutet, alles andere FEHLER. Welcher Fehler kann dann aus dem Wert bestimmt werden (interessiert hier aber nicht).

HTH
Ede
Biber
Biber 02.02.2010 um 12:31:19 Uhr
Goto Top
Moin edepfau,

nur falls jemand das über eine Suchmaschine findet:

Diesen Satz.
...wird damit eine Umgebungsvariable namens errorlevel gemeint. Die gibt es in der Regel aber nicht!
möcte ich ungern so stehen lassen.

Wenn du einfach z.B. die Hilfe zu SET (oder anderen) aufrufst und nach "errorlevel" suchst, liest Du [in Zeile 03], was ich meine:
>set /?|find /i "errorlev"  
Der SET-Befehl legt den ERRORLEVEL mit 1 fest, wenn der Variablenname nicht
%ERRORLEVEL% - expandiert zum aktuellen ERRORLEVEL-Wert.

%errorlevel% als dynamische Variable gibt es IMMER und (deswegen ja dynamisch) IMMER nach jeder abgesetzten Befehlszeile aktualisiert/expandiert.
So wie auch %date%, %time%, %random%. Diese Variablen werden allesamt nicht bei SET angezeigt, aber "es gibt sie schon".

Besonderheit bei der Prüfung des ERRORLEVELs ist aber unter anderem, dass es neben der üblichen Syntax "IF %errorlevel% == n" auch noch die Syntax "IF ERRORLEVEL n" gibt... ohne Prozentzeichen drumherum und ohne Gleichheitszeichen. Und dieses "IF ERRORLEVEL n" wird eben nicht wie ein "IF %errorlevel% ==.." bei Beginn der Ausführung aufgelöst.

Grüße
Biber
edepfau
edepfau 02.02.2010 um 12:53:32 Uhr
Goto Top
Das stimmt so nicht, und weil diese Meinung so weit verbreitet ist, habe ich auf den Unterschied hingewiesen.

Die errorlevel Variable ist eben keine Umgebungsvariable, d.h. wird nicht im Environment definiert, abgefragt oder gelöscht. MS hat die Syntax der der Umgebungsvariablen angepasst, um dem User nicht noch eine Schreibweise zuzumuten (z.B. $errorlevel$). Und weil das keine Umgebungsvariable ist, braucht man auch keine delayed expansion (den Befehl kann man oben gleich löschen).
Wenn man den Unterschied kennt, dann wird man auch nicht versucht sein,
set /a ERRORLEVEL 3
zu tippen. Das klappt zwar, aber dann hat man eine Umgebungsvariable gleichen Namens erzeugt, die völlig statisch ist. D.h. man kann den Rückgabewert von Befehlen nicht mehr (mit %errorlevel%) abfragen.

Hier ist ein Artikel, der das beschreibt (aus MSDN): The Old New Thing - ERRORLEVEL is not %ERRORLEVEL%
in http://blogs.msdn.com/oldnewthing/archive/2008/09/26/8965755.aspx

Gruß,
Ede
Biber
Biber 02.02.2010 um 13:14:51 Uhr
Goto Top
Moin edepfau,

ich denke, da hast du etwas missverstanden.
Aber ist mir auch nicht so wichtig und ich denke, die MitleserInnen können sich in dem angeführten Blog-Artikel und in der Hilfe am CMD-Prompt ja selbst ein Bild.
machen.

Dieses absurde Beispiel mit dem "SET ERRORLEVEL=whatever"... ja hey! Das ist Dönekens.

Du kannst beispielsweise auch die dynamische %random%-Variable auf 42 setzen.
Und den Wert 42 behält sie auch..face-wink
>set random=42

>echo %random%
42

>echo %random%
42
... toller Plan... face-wink
Aber sobald du deine "lokale Privat-Übersteuerung" der im CMD.exe-Environment immer vorhandenen %random%-Variablen wegknallst...
>set random=
... und die "Überlagerung" weg ist, dann siehst du wieder den eigentlichen Zustand.
>echo %random%
24795 '-- bzw. irgendein anderer Zufallswert >=0 <=32000irgendwas  

Aber, wie geschrieben, es ist mir auch nicht so wichtig.
Selbst mit falscher Herleitung würde ja mein Workaround dem didie08 bei seinem begrenzten Problem nicht schaden.

Grüße
Biber
didie08
didie08 02.02.2010 um 13:31:02 Uhr
Goto Top
Hallo,

Vielen Dank für eure engagierte Hilfe

Mit folgendem Code ist mein Problem gelöst.

for /f "tokens=1,2,3,4 delims= " %%i in ('findstr "name" text1.txt') do (  
	findstr "%%j" text2.txt >nul  
	if ERRORLEVEL 1 echo  %%i %%j %%k %%l>>text2.txt
)

Gruß
didie08
bastla
bastla 02.02.2010 um 15:08:01 Uhr
Goto Top
Hallo (auch an alle, die nicht von Google hierher geführt wurden face-wink)!

Nur als Ergänzung:
@echo off & setlocal enabledelayedexpansion

echo So nicht:
for %%i in (B: C:) do (
    dir %%i >nul 2>&1
    if %errorlevel% neq 0 (echo Fehler) else (echo OK)
)

echo\
echo ... aber so
for %%i in (B: C:) do (
    dir %%i >nul 2>&1
    if !errorlevel! neq 0 (echo Fehler) else (echo OK)
)

echo\
echo ... oder so
for %%i in (B: C:) do (
    dir %%i >nul 2>&1
    if errorlevel 1 (echo Fehler) else (echo OK)
)

echo\
echo ... oder auch so
for %%i in (B: C:) do (
    dir %%i >nul 2>&1 || (echo Fehler) && (echo OK)
)
Das Beispiel bekommt die größte Aussagekraft, wenn es kein Laufwerk B: gibt. face-wink

[Edit] Letzte Variante benötigt umgekehrte Schreibweise - siehe unten ... [/Edit]

Grüße
bastla
Biber
Biber 02.02.2010 um 16:05:12 Uhr
Goto Top
Moin bastla,

na, wenn denn so viele Such-MaschinistInnen hier erwartet werden, dann sollten wir denen ja was bieten.

Dann noch eine kleine Fussnote.
Wenn ich deinen Lehrschnipsel so hin drehe, dass auch die Interessierten mit vorhandenem B:-Laufwerk was zum Staunen haben und zum Testen das Laufwerk @:\ abprüfe:
:: -- bastlasEL.cmd Demoschnipsel für Errorlevel-Abfrage
@echo off & setlocal enabledelayedexpansion
:: --- geprüft werden immer die Laufwerke @:\ [nicht da] und C: ["immer" da]  
echo So nicht:
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if %errorlevel% neq 0 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... aber so
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if !errorlevel! neq 0 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... oder so
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if errorlevel 1 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... oder auch so
for %%i in (@: C:) do (
    dir %%i >nul 2>&1 || (echo %%i Fehler) && (echo %%i OK)
)

dann ist die Ausgabe wie folgt:
>BastlasEL.bat
So nicht:
@: OK
C: OK

... aber so
@: Fehler
C: OK

... oder so
@: Fehler
C: OK

... oder auch so
@: Fehler
@: OK
> Bitte auf die letzten beiden Ausgabezeilen achten!!
aber fällt leider in die Kategorie works as designed...
Das macht er nur, WENN ein Fehler aufftrat... und dann macht er ZUSÄTZLICH die Anweisung rechts des "&&".

Grüße
Biber
bastla
bastla 02.02.2010 um 17:19:06 Uhr
Goto Top
@Biber

Na dann machen wir's doch so (und ich wollte es ohnehin schon vorhin umdrehen *grummel*):
echo ... oder doch so 
for %%i in (@: C:) do ( 
    dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
)
Dann wird ein schönes "If - Then - Else" mit folgendem Ergebnis
... oder doch so
@: Fehler
C: OK
draus ...
BTW: Wo ist denn vorhin das "C:" geblieben?
@: Fehler 
@: OK
Grüße
bastla
Biber
Biber 02.02.2010 um 21:31:34 Uhr
Goto Top
Moin bastla,

Zitat von @bastla:
BTW: Wo ist denn vorhin das "C:" geblieben?
@: Fehler 
@: OK
Na, probier doch den von mir geposteten Schnipsel mal ... das ist wirklich die Original-Demo-Ausgabe.

Interpretation:
In Summe
@: Fehler 
@: OK


In Summe
{ Näherungswert für FDP-Wirtschaftskompetenz }
Grüße
Biber
bastla
bastla 02.02.2010 um 22:04:14 Uhr
Goto Top
@Biber
OK, Nachmittagstief vorbei - ist klar ... face-smile
das ist wirklich die Original-Demo-Ausgabe.
hätte ich auch nie nicht angezweifelt ...

Aber die umgekehrte Variante
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
tut bei mir tatsächlich, was sie soll.

Grüße
bastla
Biber
Biber 02.02.2010 um 22:17:56 Uhr
Goto Top
Moin bastla,

Zitat von @bastla:
@Biber
OK, Nachmittagstief vorbei - ist klar ... face-smile
Tja, wenn die Montage manchmal etwas länger dauern... kenn ich.
Aber die umgekehrte Variante ... tut bei mir tatsächlich, was sie soll.

Na ja sagen wir lieber... works as designed...

Wenn du das Konstrukt so formulierst...
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)

[edit]
BullShit.... Theorie wurde schnell widerlegt... siehe unten.
[/edit]

Da diese Wahrscheinlichkeit doch eher zu vernachlässigen ist... hmm...
Ich würde es (wegen der Lesbarkeit) gleich ganz weg lassen.

Grüße
Biber

P.S. Jezz' haben die GooglerInnen aber wirklich was zu lesen.... face-wink
bastla
bastla 02.02.2010 um 22:25:04 Uhr
Goto Top
Ach so, hatte mich schon über den Krach vorhin gewundert ... face-wink

Aber ernsthaft: Welche andere Erklärung hättest Du noch für die (ebenfalls originale) Ausgabe
... oder doch so 
@: Fehler 
C: OK
Grüße
bastla
Biber
Biber 02.02.2010 um 22:38:25 Uhr
Goto Top
Tja, bastla,

das hatte ich fast schon befürchtet, dass unsere Rechner unterschiedliche Ergebnisse liefern.

Mein reduzierter Demo-Schnipsel mit aktuellem Ausgabe-Ergebnis als letzte Codezeilen (ab Zeile 32 nach dem "goto :eof")..
:: -- bastlasEL.cmd Demoschnipsel für Errorlevel-Abfrage
@echo off 
:: & setlocal enabledelayedexpansion
goto :theLast
echo So nicht:
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if %errorlevel% neq 0 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... aber so
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if !errorlevel! neq 0 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... oder so
for %%i in (@: C:) do (
    dir %%i >nul 2>&1
    if errorlevel 1 (echo %%i Fehler) else (echo %%i OK)
)

echo\
echo ... oder auch so
:TheLast Anmerkung Lw. C: und D: existieren; @: und V: nicht
for %%i in (@: C: D: V:) do (
    dir %%i >nul 2>&1 || (echo %%i Fehler) && (echo %%i OK)
)
goto :eof
Ausgabe:
(=22:31:56  D:\temp=)
>BastlasEL.bat
@: Fehler
@: OK
V: Fehler
V: OK
(=22:34:07  D:\temp=)

Von Laufwerk C: und D: ist nix zu sehen, nix zu hören...
XP Prof SP3, handelsübliche Client-Config... mehr hab ich nicht getestet.

Grüße
Biber
bastla
bastla 02.02.2010 um 22:49:39 Uhr
Goto Top
Hallo Biber!

Deine Zeile 29 sollte so aussehen:
dir %%i >nul 2>&1 && (echo %%i OK) || (echo %%i Fehler)
Bei mir übrigens erfolgreich unter
  • XP Pro SP2
  • Uralt-Vista aus der VM
  • W7 Pro, kein SP face-wink

Grüße
bastla
Biber
Biber 02.02.2010 um 22:58:55 Uhr
Goto Top
Okay, okay, bastla,

ich nehme alles zurück (auch alle Meteoriten-Theorien) und bestätige deine Test auch für Win XP Pro SP3.

>BastlasEL
@: tilt
C: OK
D: OK
V: tilt

Jetzt kommen wir bestimmt in die Top-Ten-Beiträge mit einem Thread, der seit heute mittag auf "Erledigt" steht...

Grüße
Biber
bastla
bastla 02.02.2010 um 23:06:52 Uhr
Goto Top
Hallo Biber!
Jetzt kommen wir bestimmt in die Top-Ten-Beiträge
Huch, wenn der Google-Bot das auch noch mitbekommt ... face-wink

Grüße
bastla
Mehr von didie08didie08Letzte 10 Zeilen aus Dateien lesendidie08 - 7 Kommentaredidie08For Schleife mit Datei umbenennungdidie08 - 7 Kommentaredidie08Problem mit forschleife bei pfaden mit leerzeichendidie08 - 2 Kommentaredidie08For schleife nur in Zeitfenster ausführendidie08 - 3 Kommentare
Heiß diskutiert
superfun2k24Sophos SFOS 20 DNAT funktioniert nichtsuperfun2k24 - 26 Kommentareuser217Kaufberatung Hardware - Hyper-V Cluster 3 Nodesuser217 - 25 KommentarePharaunIntel-E810 QSFP28 to Mikrotik QSPF+ mit 40Gbit VerbindungPharaun - 24 Kommentareprplemk2Testumgebung bauen (Grundlegend)prplemk2 - 19 KommentareaufdemmarsHP Z620 USB hat kein Strom beim Startenaufdemmars - 17 KommentareTJ.Hooker74Dom.Admin-Passwort ändern - Auswirkungen auf EX, HCW, AADCTJ.Hooker74 - 15 KommentaremaisenkaiserSwitch ohne STP ins Netzwerkmaisenkaiser - 13 KommentareUnluckyProccess1999Creo 4.0 Lizenz Server (LMTOOLS)UnluckyProccess1999 - 13 KommentareJudgelgZertifikate in die Exchange Online GAL hochladenJudgelg - 13 KommentareadmtechEntwicklertagebuch: Release 6.4 - Filteradmtech - 13 KommentareleberkaeseFB7590 ISDN Fax-Funktionleberkaese - 12 KommentareHemingwayWord Makro soll aktuelle Datei regelmäßig kopieren und speichernHemingway - 11 Kommentare