Frage von ChrizzRocks, 8

Batch, Warum macht mein If Statement nicht was es soll?

Hi, habe euch im anhang ein batch script das einfach nicht macht was es soll... habe auch schon versucht die einzelnen set Befehle hinter dem if mit & zu verknüpfen, leider gleich erfolglos. den ersten buchstaben sucht es sich richtig aber die folgenden 5 nichtmehr.

ich veresteh nur leider nicht warum, das if Statement ist doch sauber Programmiert so wie es da steht. Bitte beachtet nur die if Statements, die schleife drüber bitte so lassen :D

Hier mein Batch script:

https://mega.nz/#!HR9nSCbB!ZRMXAxdXPnvQiJowmNPIksQRbn8QQrPwhq7D5WHZKlg

Antwort
von MarkusGenervt, 5

Bitte poste Deine Batch irgendwo online. Ich werde mir ganz sicher nichts blind herunter laden!

Kommentar von ChrizzRocks ,

@echo off
REM Variablen definieren
set V1=0 & set V2=0 & set V3=0 & set V4=0 & set V5=0 & set Counter=0

set /p BU1=Inhalt

:loop
if "%Counter%"=="0" goto 0
if "%Counter%"=="1" goto 1
if "%Counter%"=="2" goto 2
if "%Counter%"=="3" goto 3
if "%Counter%"=="4" goto 4
if "%Counter%"=="5" goto 5
if "%Counter%"=="6" goto 6
if "%Counter%"=="7" goto 7
if "%Counter%"=="8" goto 8
if "%Counter%"=="9" goto 9
if "%Counter%"=="10" goto 10
if "%Counter%"=="11" goto 11

:0

set "Drive=%BU1:~,1%"
echo %Drive%
set Var1=%Drive%
echo %Var1%
echo -
echo %Counter%
set /a Counter=%Counter%+1
echo %Counter%
pause
goto Start

:1

set "Drive=%BU1:~1,1%"
echo %Drive%
set Var1=%Drive%

set A1=%V1%
set B1=%V2%
set C1=%V3%
set D1=%V4%
set E1=%V5%

set /a Counter=%Counter%+1
echo %Var1%

echo -
echo %A1% %B1% %C1% %D1% %E1%
echo -
pause
goto Start

:2
set "Drive=%BU1:~2,1%"
echo %Drive%
set Var1=%Drive%

set A2=%V1% & set B2=%V2% & set C2=%V3% & set D2=%V4% & set E2=%V5%

set /a Counter=%Counter%+1

echo -
echo %A2% %B2% %C2% %D2% %E2%
echo -

pause
goto Start

:3
set "Drive=%BU1:~3,1%"
echo %Drive%
set Var1=%Drive%

set A3=%V1% & set B3=%V2% & set C3=%V3% & set D3=%V4% & set E3=%V4%

set /a Counter=%Counter%+1

echo -
echo %A3% %b3% %C3% %D3% %E3%
echo -

pause
goto Start

:4
set "Drive=%BU1:~4,1%"
echo %Drive%
set Var1=%Drive%

set A4=%V1% &set B4=%V2% & set C4=%V3% & set D4=%V4% & set E4=%V5%

set /a Counter=%Counter%+1

echo -
echo %A4% %B4% %C4% %D4% %E4%
pause
goto Start

:5
set "Drive=%BU1:~5,1%"
echo %Drive%
set Var1=%Drive%

set A5=%V1% & set B5=%V2% & set C5=%V3% & set D5=%V4% & set E5=%V5%
set /a Counter=%Counter%+1

echo -
echo %A5% %B5% %C5% %D5% %E5%
echo -
pause
goto Start

:Start

echo start
if "%Var1%"=="A" ( set V1=0
set V2=0
set V3=0
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="B" ( set V1=0
set V2=0
set V3=0
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="C" ( set V1=0
set V2=0
set V3=0
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="D" ( set V1=0
set V2=0
set V3=1
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="E" ( set V1=0
set V2=0
set V3=1
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="F" ( set V1=0
set V2=0
set V3=1
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="G" ( set V1=0
set V2=0
set V3=1
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="H" ( set V1=0
set V2=1
set V3=0
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="I" ( set V1=0
set V2=1
set V3=0
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="J" ( set V1=0
set V2=1
set V3=0
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="K" ( set V1=0
set V2=1
set V3=0
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="L" ( set V1=0
set V2=1
set V3=1
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="M" ( set V1=0
set V2=1
set V3=1
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="N" ( set V1=0
set V2=1
set V3=1
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="O" ( set V1=0
set V2=1
set V3=1
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="P" ( set V1=1
set V2=0
set V3=0
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="Q" ( set V1=1
set V2=0
set V3=0
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="R" ( set V1=1
set V2=0
set V3=0
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="S" ( set V1=1
set V2=0
set V3=0
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="T" ( set V1=1
set V2=0
set V3=1
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="U" ( set V1=1
set V2=0
set V3=1
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="V" ( set V1=1
set V2=0
set V3=1
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="W" ( set V1=1
set V2=0
set V3=1
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="X" ( set V1=1
set V2=1
set V3=0
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="Y" ( set V1=1
set V2=1
set V3=0
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="Z" ( set V1=1
set V2=1
set V3=0
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="?" ( set V1=1
set V2=1
set V3=1
set V4=0
set V5=0
goto Loop
)
if "%Var1%"=="!" ( set V1=1
set V2=1
set V3=0
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="/" ( set V1=1
set V2=1
set V3=1
set V4=0
set V5=1
goto Loop
)
if "%Var1%"=="+" ( set V1=1
set V2=1
set V3=1
set V4=1
set V5=0
goto Loop
)
if "%Var1%"=="-" ( set V1=1
set V2=1
set V3=1
set V4=1
set V5=1
goto Loop
)
if "%Var1%"=="." ( set V1=0
set V2=0
set V3=0
set V4=0
set V5=0
goto Loop
)

goto Loop

Kommentar von ChrizzRocks ,

Der teil mit den ifs, welcher nicht das tut was er soll beginnt ab :Start

Kommentar von MarkusGenervt ,

Erst mal solltest Du Dich von solchen unsäglichen Konstruktionen wie

set V1=0 & set V2=0 & set V3=0 & set V4=0 & set V5=0 & set Counter=0

verabschieden. Die "&"-Verknüpfung sollte nie mit SET zusammen benutzt werden. Damit sparst Du auch kein Byte, sondern benutzt noch zusätzlich eines mehr.

Außerdem musst Du numerische Variablen auch von Anfang an so deklarieren, denn eine interne Typ-Umwandlung findet nicht statt.

Sowas hier

set /a Counter=%Counter%+1

geht auch kürzer mit

set /a Counter+=1

Das geht übrigens mit allen Rechenoperationen.

––––––––––

Doch was wirklich scheitern muss ist die Setzung von Variablen in einem Sub-Prozess wie IF oder FOR.

Dafür gibt es aber eine Trick:

SetLocal EnableDelayedExpansion

Damit werden auch diese Variablensetzungen ausgewertet, erfordern aber eine andere Variablen-Syntax. Das "%" muss durch das "!" ersetzt werden, also z.B. "!counter!" anstatt "%counter%". Teilweise funktionieren Variablen mit dem "%"-Zeichen immer noch, aber das hängt von verschiedenen anderen Prozessen ab und das Ergebnis ist auch dann nicht immer sofort abrufbar. Man sollte es daher vermeiden, wenn man mit dem genannten SETLOCAL-Parameter arbeitet. Der Befehl hat Gültigkeit bis zum Ende des BAtch-Prozesses oder durch

SetLocal DisableDelayedExpansion

oder

EndLocal

Noch ein Tipp:

Den ganzen schreibkram hättest Du Dir sowas von sparen können, wenn Du einfach den FOR-Befehl für Listen genommen hättest. Allerdings funktioniert GOTO nicht innerhalb von FOR. Dazu kannst Du aber CALL benutzen (z.B. "CALL :Start").

Oder unter ":loop" hätte auch gereicht

goto %counter%

So einfach geht das.

Batch ist so einfach. Und für jeden Befehl in CMD gibt es eine Hilfe mit "/?". Das solltest Du mal nutzen und genau durchlesen. SET und FOR sind zwar recht komplex, aber nach zwei/drei Mal lesen wird es klarer.

Stauch den ganzen überflüssigen Code mal zusammen. Die ganze Batch lässt sich locker auf eine übersichtliche Länge komprimieren und ohne Befehlsverkettung. ;)

Kommentar von ChrizzRocks ,

das mit dem counter wusste ich nicht, es hat ja aber trzdm getan. das mit Delayedexpansion hab ich noch nie im leben gesehen, und wie du gemerkt hast sind meine batchkentnisse sehr sehr anfänglich. komischerweise, geht es jetzt in einem anderen textdokument. ich habe eunfach die set befehle wieder mit & verknüft und komischerweise geht es. aber warum soll ich mich von solchen konstruktionen verabschieden? die größe der datei ist mir relativ unwichtig, ich wollte es nur übersichtlicher gestalten :D

Kommentar von MarkusGenervt ,

komischerweise, geht es jetzt in einem anderen textdokument.

Was meinst Du? Welches Text-Dokument und was geht?

ich habe eunfach die set befehle wieder mit & verknüft und
komischerweise geht es. aber warum soll ich mich von solchen
konstruktionen verabschieden?

Weil es in deinem Fall auch noch gerade funktioniert. Aber unter bestimmten Werte-Bedingungen kann auch eine String-Verkettung passieren- Das problem ist eben, das SET – je nach den Umständen – auch mal einfach alles nach dem Gleichheitszeichen auswertet. Da sind früher oder später Fehler vorprogrammiert, die dann auch noch richtig problematisch werden können, wenn Du das z.B. auch mit einer Pipe oder Umleitung versuchst.

Also beschränke diese Sonderfunktionen besser auf "normale" Befehle, die auch "normal" auf die Befehls-Eingabe (Parameter) reagieren.

die größe der datei ist mir relativ unwichtig,

Ja, das war auch nur ein Anspielung auf alte Zeiten, als Batch noch sehr viel wichtiger war und als der Festspeicher noch so klein war, dass es auf jedes eingesparte Byte ankam. Schon mal was von einer 5¼''-Diskette gehört? Google das mal. Das war das, was zur Verfügung stand, als es Festplatten nur den Universitäten gab.

ich wollte es nur übersichtlicher gestalten :D

Tja, Übersichtlichkeit geht beim Programmieren etwas anders. Über so was regt sich eigentlich jeder ordentliche Programmierer auf, denn man verliert schnell den Überblick, wo ein Befehl aufhört und wo der Nächste beginnt. Das ist dann bei der Fehlersuche – welche sehr schnelle und Übersichtlich sein muss – ein echter Krampf.

Diese Befehlsverkettung ist für die Eingabeaufforderung gedacht, weil man dort nicht zeilenweise die Anweisungen angeben kann, wie in einem Skript.

Damit kannst Du mal was basteln, wenn Du mit Bash (=> Linux) arbeitest. Dort sind Verkettungen sehr viel robuster und vielseitiger als unter Windows.

das mit dem counter wusste ich nicht, es hat ja aber trzdm getan.

Ja, das geht auch beides. Nur ist die zweite Option sehr viel kürzer und schneller, weil der "%counter%"-Teil in der Rechnung nicht erst über den Batch-Interpreter übersetzt und umgewandelt werden muss. Das ist aber nur ein unbedeutender Geschwindigkeitsgewinn bei modernen Rechnern. Aber zu einem guten Programmierer, gehört auch strikter Optimierungs-Wille – man weiß nie, wann es mal darauf ankommt.

Batch ist zwar jetzt nicht so wirklich anspruchsvoll – eigentlich kenne ich keine Skript-Sprache, die noch primitiver ist –, aber man kann gerade hierbei durch den extrem eingeschränkten Befehlssatz hervorragend lernen, um die Ecke zu denken und Lösungen finden, die eigentlich gar nicht gehen. Es fordert den Intellekt.

Hier noch eine kleine Zusammenfassung der Befehle:

HELP

Das ist so blöd einfach, dass man einfach nicht drauf kommt ;o))

Für jede Hilfe zu den aufgelisteten Befehlen kannst Du auf zwei Wegen Hilfen erhalten:

HELP Befehl
Befehl /?

Also, auch wenn ich schon mehr als 30 Jahre damit arbeite, muss ich zugeben, dass ich ab und zu nochmal bei FOR oder so nachschauen muss, wenn nach langer Zeit mal wieder was besonderes Anliegt.

"Wissen" heißt nicht alles zu wissen, aber man muss wissen, wo es steht!

Kommentar von ChrizzRocks ,

5 1/4 Zöller, wie ich sie liebe XD

ich habe die set befehle nochmal mit &verknüpft, und in ein leeres txt kopiert, dann ganz primitiv eine einzige Variable hinzugefügt und es ging wieder. hier der code:

@echo off
set/p Eingabe=Wort

if %Counter%=="1" goto 1

set "Drive=%Eingabe:~,1%"
echo %Drive%

:
echo start
if "%Var1%"=="A" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=0 &set Buchstabe5=1
)
if "%Var1%"=="B" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="C" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="D" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="E" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="F" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="G" (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="H" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="I" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="J" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="K" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="L" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="M" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="N" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="O" (
set Buchstabe1=0 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="P" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="Q" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="R" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="S" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="T" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="U" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="V" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="W" (
set Buchstabe1=1 & set Buchstabe2=0 & set Buchstabe3=1 / set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="X" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="Y" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="Z" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="?" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=0
)
if "%Var1%"=="!" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=0 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="/" (
set %Buchstab1%=1 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=0 & set Buchstabe5=1
)
if "%Var1%"=="+" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=0
)
if "%Var1%"=="-" (
set Buchstabe1=1 & set Buchstabe2=1 & set Buchstabe3=1 & set Buchstabe4=1 & set Buchstabe5=1
)
if "%Var1%"=="." (
set Buchstabe1=0 & set Buchstabe2=0 & set Buchstabe3=0 & set Buchstabe4=0 & set Buchstabe5=0
)
set Variable=Hallo
:loop
echo %Buchstabe1%
echo %Buchstabe2%
echo %Buchstabe3%
echo %Buchstabe4%
echo %Buchstabe5%
echo %Variable%
pause

es sind aber andere Probleme aufgetreten, da ich ja noch nicht mit delayedexpansion arbeite. die Ausgabe von %Buchstabe1%-%Buchstabe5% ging nicht. es kam immer nur Echo ist ausgeschaltet in der Konsole (deswegen habe ich %Variable% hinzugefügt, um zu schauen ob es an der Verkettung liegt.)

zum Optimierungswille, ich wollte es erstmal zum laufen bringen, und dann solche Sachen optimieren. das mit dem Delayedexpansion wird auf jeden fall gemacht. aber für die Benutzeroberfläche möchte ich noch bat-box benutzen, also sollte lieber erstmal alles gut laufen.

noch eine andere Frage, ich hatte mal ein Batch Menü, bei welchem die Konsole sobald, ich eine zahl oder einen Buchstaben eingegeben habe, es ohne Entertaste diese eine zahl/ziffer in die Variable speichert. ich weiß nur nicht mehr wie das hieß un ging, ich glaube iwas mit choice oder so... kannst du mir sagen wie der befehl dafür heißt?

Kommentar von MarkusGenervt ,

Also ohne den SETLOCAL-Befehl wirst Du auf jeden Fall scheitern. Entweder Du machst das oder Du drehst Dich hier weiter im Kreis. Das funktioniert so einfach nicht!

Da musst Du Dich übrigens auch nicht über die ECHO-Meldung wundern, wenn die Variablen leer sind und sonst kein Text ausgegeben werden kann.

Ein kleiner Trick, um diese Null-Text-Ausgaben ohne diese ECHO-Meldung hinzubekommen:

echo.%MyVar%

Hiermit wird eine Leerzeile ausgegeben, wenn %MyVar% leer ist.

Das geht auch ganz allgemein, um nur eine Leerzeile auszugeben:

echo.

Somit funktioniert es so besser:

echo.%Buchstabe1%-%Buchstabe2%-[…]

Ach und nimm besser einen kürzeren Variablen-Namen. Mit "%BuchstabeX%" schreibst Du Dir ja einen Wolf.

Hier noch ein weites Trick-Beispiel:

set Buchstabe5=0
for %%C in (A,C,E,G,[…],"!","/","-") do if "%Var1%" == "%%~C" set Buchstabe5=1

Das machst Du NUR für die 1er-Werte. Damit hast Du die ganze Latte Deiner IF-Abfragen auf 10 Zeilen reduziert.

Bei der Gelegenheit – noch eine Fehler-Korrektur:

if "%Counter%"=="1" goto 1

So wie Du das hattest, wird der niemals zu ":1" gehen, weil nach der Variablen-Auflösung das heraus kommt und das ist nicht gleich:

if 1=="1" goto 1

Übrigens ist es völlig unnötig den Batch-Code in einer TXT-Datei zu maskieren. Solange die Datei als BAT-, CMD-, oder NT-Datei nicht manuell gestartet wird, wird die Ausführung auch nie von "Geisterhand" gestartet.

Falls sich das allerdings durch die Verwendung von Notepad so ergab, muss ich Dich darauf hinweisen, dass Notepad einen anderen Zeichensatz benutzt, als Batch. Solange sich Deine Text-Ausgabe auf den ASCII-Satz beschränkt, ist das noch kein Problem. Aber sobald ANSI-Zeichen (CP1250) hinzukommen, wird die Ausgabe falsche Zeichen liefern, denn Batch nutzt den OEM-Zeichensatz (CP437/CP850). Google das mal, das könnte wichtig sein.

Teste das mal. Erstelle mit Notepad folgende Batch und lass die mal laufen (durch den pause-Befehl kannst Du die Batch auch aus der GUI anklicken) :

@echo off
echo.
echo.Ein gesunder Baum weiß, dass er einmal schöne Früchte trägt.
echo.
pause

Keine passende Antwort gefunden?

Fragen Sie die Community