heinze
Goto Top

CMD, Errorlevel Findstrg entspricht nicht den Erwartungen

WIN10
Commandline /Batch

Hallo Leute

ich versuche gerade wieder mit Findstr in einer Batch Ergebnisse zu erzielen.

Findstr soll eine txt nach einem genauem Muster durchsuchen und ich will dann den ERRORLEVEL weiter verarbeiten:

Wenn ERRORLEVEL is NOT == 0 dann...

Die Daten im zu durchsuchendem txt liegen im Format
Vorname - Name
vor
Das Trennzeichen ist jeweils der Bindestrich.

Aktuell versuche ich es mit folgender Syntax in einer Batch:

@echo on &setlocal EnableDelayedExpansion

Set "gesucht=xxx"  

findstr /ic:%gesucht%  "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  
Echo originalerrorl ---%ERRORLEVEL%
echo %gesucht%

Da der Suchstring xxx nicht im txt-File vorkommt ist die Errorlevelausgabe 1, somit nicht gefunden
Gebe ich stattdessen einen Suchstring ein der im txt-File vorhanden ist erhalte ich ebenfalls ERRORLEVEL 1 statt der erwarteten 0

C:\Windows\System32>G:\_AA-KCCNsuche\007_sucheIn005.bat

C:\Windows\System32>Set "gesucht=Ana"  

C:\Windows\System32>findstr /ic:Ana  "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  

C:\Windows\System32>Echo originalerrorl ---1
originalerrorl ---1

C:\Windows\System32>echo Ana
Ana


Was mach ich hier grundlegend falsch?

Gruss Heinze

Content-ID: 3574426956

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

Ausgedruckt am: 25.11.2024 um 10:11 Uhr

rubberman
rubberman 07.08.2022 um 16:58:53 Uhr
Goto Top
Ist das Charset deiner Textdatei mglw. UTF-16?

Nicht die Ursache, aber üblicherweise sollte die Suchzeichenfolge in Anführungszeichen gesetzt werden, à la
findstr /ic:"%gesucht%" ...

Steffen
Heinze
Heinze 07.08.2022 um 17:50:49 Uhr
Goto Top
Hallo rubberman

ich habe nun mit dem Windows Editor ein neues Textfile erstellt.
Habe aus der bestehenden einen Teil der Einträge rauskopiert und in das neue txt-File eingefügt,
Habe einen anderen Suchstring verwendet (der bestimmt auch so vorkommt:

Wieder erhate ich den ERRORLEVEL 1
Habe mal mit den handelsüblichen "" rumprobiert und auch die Befehlserweiterung mal aus geRMT.

C:\Windows\System32>G:\_AA-KCCNsuche\007_sucheIn005.bat

C:\Windows\System32>Set "gesucht=Anuhea"  

C:\Windows\System32>findstr /ic:**"Anuhea"**  "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  

C:\Windows\System32>Echo originalerrorl ---1
originalerrorl ---1

Immer der gleiche Erfolg: ERRORLEVEL 1
Gruss Heinze
rubberman
rubberman 07.08.2022 um 18:44:56 Uhr
Goto Top
Zitat von @Heinze:
...**"Anuhea"**...  
Was zur Hölle ... ? face-big-smile Hast du hier versucht Text in Codetags fett hervorzuheben oder hast du das wirklich so im Code stehen?

Normalerweise erzählen dir einigermaßen moderne Texteditoren in der Statusleiste welche Zeichencodierung eine Datei hat. Egal. Ich gehe immer noch davon aus dass es UTF-16 ist, wo bspw. ein "Z" nicht einfach nur das Byte 5A ist, sondern durch 2 Bytes 5A 00 repräsentiert wird. Ein Tool wie findstr.exe erwartet aber mit ANSI gefüttert zu werden und wird somit UTF-16 nicht so verarbeiten, wie du hoffst. Ist halt so wenn man unbedingt noch mit Batch herumwerkeln will.

Workaround: Du musst eine Konvertierung vornehmen. Das TYPE Kommando macht das für dich. Den resultierenden Textstream leitet man per Pipe an FINDSTR.
type "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"|findstr /ic:"%gesucht%"  

Steffen
Heinze
Heinze 08.08.2022 um 10:12:53 Uhr
Goto Top
Hallo rubberman

Danke für deine Hilfe,
Leider hat dein Syntaxvorschlag nicht funktioniert.
Ich habe dann mal mit Nottepad++ das 005_SortUniq-v003.txt geprüft, dabei wurde mir KEINE Codierung angezeigt, alle anderen txts werden mir mir UTF-8 angezeigt.

Ich habe dann das 005_SortUniq-v003.txt im Notepad++ nach ANSI codiert und schon klappte es auch mit meiner Syntax.
Ich habe nun alle in diesm Projekt beteilgten Files und .bats geprüft : alles uiin UTF-8.
In früheren Projekten sind jdoch die meisten Files als ANSI codiert.

Gibts es eine Lösung mittels script (CMD) die Files der einfachheit halber nach ANSI zu codieren ? und was handele ich mir dabei ein?


Das File 005_SortUniq-v003.txt ist das Ergebniss meherer Batchdurchläufe:

@echo off &setlocal EnableDelayedExpansion


>"G:\_AA-KCCNsuche\003_DIR-Ablagepfade-Ergebnis.txt" (for /f "usebackq delims=" %%a in ("G:\_AA-KCCNsuche\001_Ablagepfade.txt") do for /f "delims=" %%b in ('dir /b /s /a-d "%%a"') do @echo %%~nb)  

danach sortiert:

sort /u "G:\_AA-KCCNsuche\003_DIR-Ablagepfade-Ergebnis.txt" >> "G:\_AA-KCCNsuche\005_SortUniq-v.003.txt"  

Warum wird mir bei der Ausgabe des SORT in das G:\_AA-KCCNsuche\005_SortUniq-v.003.txt die Codierung verändert (von UTF-8 in NIX)

Evtl hast du einen Vorschlag wie ich alle Files in ANSI bekommen, wenns denn sinnvoll ist.
Powershell ist für mich leider keine Lösung, nicht weil ich nicht wollte, aber selbst meine DOS-Kenntnisse stammen noch aus einer Zeit das noch nicht mal die Befehlserweiterung gab, also schon arg lange, ca gut 20 Jahre.


Zitat: Was zur Hölle ... ? face-big-smile Hast du hier versucht Text in Codetags fett hervorzuheben:

Genau das wollte ich.. Im Code steht das natürlich nicht.

Herzliche Dank schon mal im voraus
Heinze
rubberman
Lösung rubberman 08.08.2022 aktualisiert um 15:15:24 Uhr
Goto Top
sort /u ...
Das /U ist die Kurzform der undokumentierten Option /UNI_OUTPUT. Die erzeugt eine Ausgabe in Unicode (was in der Microsoftsprache so viel wie UTF-16 heißt). Die Ausgabe wird in dem Fall ohne vorangestelltes Byte Order Mark geschrieben. Daran verschluckt sich mglw. das TYPE Kommando und das ist evtl. auch der Grund warum dir NP++ kein Charset anzeigt.

Ich vermute du wolltest eigentlich mit Option /UNIQUE ran. Die Kurzform dafür wäre allerdings /UNIQ und nicht /U.

Steffen
Heinze
Heinze 12.08.2022 um 11:27:26 Uhr
Goto Top
Hallo Rubberman

das mit dem undokumentierten Option /u ist wohl mehr wie dumm gelaufen, danke für den Hinweis
mit der Option /UNIQUE erstellt mir nun ein schönes ANSI -Cdiertes G:\_AA-KCCNsuche\005_SortUniq-v.003.txt.
Danke für den Tip,

Leider funktioniert aber mein findstr-Errorlevel Problem nun wied ernicht gelöst:

Bei dieser Syntax kommt nun immer, ob vorhanden oder nicht die Errorlevelausgabe = 0

@echo on & setlocal EnableDelayedExpansion

Set "Playliste=G:\_AA-KCCNsuche\000_playlist.txt"  

for /f "tokens=*" %%i in (%Playliste%) do (  

Set "suchstring=%%i"  

ECHO vomSuchstring....!suchstring!
Echo vom Suchstringvari %%i
Pause
findstr /ic:"%%i" "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  
Echo originalerrorlvFindstr --- %ERRORLEVEL%

Es ist sichergestellt dass mindestens die erste Zeile (Wert: XXX) G:\_AA-KCCNsuche\000_playlist.txt nicht in der zu durchsuchende G:\_AA-KCCNsuche\005_SortUniq-v003.txt vorhanden ist.
000_playlist.txt ist jedoch noch in UTF-8 da Sie das Ergebniss aus einer Linuxauswertung ist.
Ausgabe:
Microsoft Windows [Version 10.0.19044.1889]
(c) Microsoft Corporation. Alle Rechte vorbehalten.

C:\Windows\System32>G:\_AA-KCCNsuche\007_sucheIn005TEST.bat

C:\Windows\System32>REM Set "FertigeSongs="G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  

C:\Windows\System32>Set "Playliste=G:\_AA-KCCNsuche\000_playlist.txt"  

C:\Windows\System32>for /F "tokens=*" %i in (G:\_AA-KCCNsuche\000_playlist.txt) do (  
Set "suchstring=%i"  
 ECHO vomSuchstring....!suchstring!
 Echo vom Suchstringvari %i
 Pause
 findstr /ic:"%i" "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  
 Echo originalerrorlvFindstr --- 0
)

C:\Windows\System32>(
Set "suchstring=XXX"  
 ECHO vomSuchstring....!suchstring!
 Echo vom Suchstringvari XXX
 Pause
 findstr /ic:"XXX" "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  
 Echo originalerrorlvFindstr --- 0
)
vomSuchstring....XXX
vom Suchstringvari XXX
Drücken Sie eine beliebige Taste . . .
originalerrorlvFindstr --- 0

C:\Windows\System32>(
Set "suchstring=Ana Vee - Another One"  
 ECHO vomSuchstring....!suchstring!
 Echo vom Suchstringvari Ana Vee - Another One
 Pause
 findstr /ic:"Ana Vee - Another One" "G:\_AA-KCCNsuche\005_SortUniq-v003.txt"  
 Echo originalerrorlvFindstr --- 0
)
vomSuchstring....Ana Vee - Another One
vom Suchstringvari Ana Vee - Another One
Drücken Sie eine beliebige Taste . . .
Ana Vee - Another one
Ana Vee - Another one
originalerrorlvFindstr --- 0

Was mach ich denn hier nur falsch?

Gruss Heinze
rubberman
rubberman 12.08.2022, aktualisiert am 13.08.2022 um 13:30:54 Uhr
Goto Top
Naja, jetzt bist du im Rumpf einer Schleife. Variablen in einer Kommandozeile oder einem in Klammern eingefassten Block von Kommandozeilen (wie bspw. deinem Schleifenrumpf) werden nur einmal zu ihrem Wert erweitert. Und das noch vor der Ausführung der Zeile / des Blocks. Um diese frühe Variablenerweiterung zu umgehen, schaltet man die verzögerte Variablenerweiterung mit
setlocal EnableDelayedExpansion
ein (hast du gemacht) und nutzt umschließende Ausrufezeichen statt Prozentzeichen um die Variable zu expandieren (hast du bei der ERRORLEVEL Variable nicht getan).

Übrigens: Sauberes Einrücken von Code hilft enorm bei der Lesbarkeit und somit auch dabei zu erkennen, wo du dich in einem Block befindest.
for %%i in (Liste) do (
    mach was mit Element %%i
    mehr ...
    if Bedingung (
        mach was wenn Bedingung wahr ist
        mehr ...
    ) else (
        mach was wenn Bedingung falsch ist
        mehr ...
    )
    mehr ...
)

Steffen
Heinze
Heinze 20.08.2022 aktualisiert um 14:56:03 Uhr
Goto Top
Hallo rubberman

danke für deine wertvolle Hilfe.

Ich war fest der Meinung der Errorlevel muss nicht mit !! maskiert werden da er ja sowieso nach jedem Kommande neu" befüllt" wird und nur einmal ausgelesen werden kann. Aber mit "EnableDelayedExpansion" ist die Welt halt wied ereine andere.
Danke aber nun klappts - fast.

Nun hat sich ein anderes Problem eingeschlichen (passt aber leider niht mehr Ursprungsfrage):
In einem der Suchstrings kommt ein Sonderzeichen nämlich ein ! vor.


@echo on &setlocal EnableDelayedExpansion
.
.
for /f "tokens=*" %%i in (%Playliste%) do (  
Set "suchstring="%%i""  
    
    findstr /ic:"%%i" %fertigeSongs%  
         if NOT !ERRORLEVEL! == 0 echo "%%i" >> G:\_AA-KCCNsuche\unbekannteSongs.txt  
)

Ausgabe am Monitor:


Set "suchstring=MAGIC! - Rude"  
      findstr /ic:"MAGIC! - Rude" "G:\_AA-KCCNsuche\VorhandeneLieder\005_SortUniq-v003.txt  
            if NOT !ERRORLEVEL! == 0 echo !suchstring!  1>>G:\_AA-KCCNsuche\unbekannteSongs.txt
)


Hier bleibt mir nur noch:
Batchvorgang abbrechen (J/N)? j

Ich weis ja das gehört maskiert mit den Zeichen"^ ^"
Aber wie mach ich das, es kommt ja nur einmal bei ca. 200 Zeilen vor?
Im Prinzip brauche ich das "!" nicht, ich könnte es somit löschen.

Ich hab auch was von "bastla" gefunden aber Sonderzeichen-in-batch-variable-maskieren
aber nicht verstanden.

Zur allerhöchsten Not könnte ich ja noch Linux ins Boot holen, das generiert die %Playliste%.
Aber jetzt noch Linux lernen.. hmm ich halte es da so lieber wie in deinem Post Warum PowerShell und nicht Batch?

Gruss Heinze
rubberman
rubberman 21.08.2022 aktualisiert um 01:33:37 Uhr
Goto Top
ich halte es da so lieber wie in deinem Post
Dann wärst du an diesem Punkt aber längst bei PowerShell.


<"!Playliste!" >"G:\_AA-KCCNsuche\unbekannteSongs.txt" (  
  for /f %%i in ('type "!Playliste!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "suchstring=" &set /p "suchstring="  
    if defined suchstring (findstr /ic:"!suchstring!" !fertigeSongs! >nul || echo !suchstring!)  
  )
)

Steffen