130834
26.10.2016, aktualisiert um 18:39:47 Uhr
2065
30
0
Grosses Variablen Problem ( Batch)
Hey Leute.
Ich bin auf ein doofes problem gestossen als ich durch variablen loopen wollte, da ich mir die 20x schreibweise des gleichen codes und nicht variabel nicht antun wollte.
ich kann keine Wörter welche in einer Variable gespeichert sind als Variable benutzen, d.h. keine Variable zusammenstellen und diese Zusammenstellung als variable benutzen.
Beispiel code
Danke im vorraus,
- clragon
Ich bin auf ein doofes problem gestossen als ich durch variablen loopen wollte, da ich mir die 20x schreibweise des gleichen codes und nicht variabel nicht antun wollte.
ich kann keine Wörter welche in einer Variable gespeichert sind als Variable benutzen, d.h. keine Variable zusammenstellen und diese Zusammenstellung als variable benutzen.
Beispiel code
set VariableX1=bla
set VariableX3=blub
set VariableX3=ble
set /a max=3
set /a "count=1"
:subloop
set line=variableX%count%
set worker=%%line%%
:: error ^
if "%worker%"=="line" ( echo hat nicht funktioniniert )
echo %worker%
set /a "count=%count+1"
if %count% EQU %max% goto :EOF
goto subloop
Danke im vorraus,
- clragon
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 319157
Url: https://administrator.de/contentid/319157
Ausgedruckt am: 08.11.2024 um 03:11 Uhr
30 Kommentare
Neuester Kommentar
DelayedExpansion oder call set sind deine Freunde
Gruß
setlocal ENABLEDELAYEDEXPANSION
set line=variableX%count%
echo !line!
Nein, das löst sehr wohl zum Inhalt auf! Deswegen heißt es ja delayed expansion (verzögerte erweiterung!)
Siehst du hier
Beispiel:
Siehst du hier
Beispiel:
@echo off & setlocal ENABLEDELAYEDEXPANSION
set var1=BlaBlaBla
set count=1
echo !var%count%!
enabledelayedexpansions immer standardmässig drin
Wundere dich nicht über Clashes bei Stringliteralen mit Ausrufezeichen. Faustregel: Zuweisung einer Variablen mit ausgeschalteter verzögerter Erweiterung, Verarbeitung der Variablen mit eingeschalteter verzögerter Erweiterung. Nur bei Variablen mit numerischem Inhalt spielt das keine Rolle ...Batch ist krank Versuch's mit einer anderen Sprache.
Grüße
rubberman
Hallo Endoro,
ich weiß ja schon wo die Reise hingeht (Dave's colorPrint).
Die Zeichen werden allerdings falsch dargestellt. Hab noch nicht ergründet warum ...
Grüße
rubberman (aka aGerman)
ich weiß ja schon wo die Reise hingeht (Dave's colorPrint).
@echo off
mode con cols=90 lines=40
setlocal DisableDelayedExpansion EnableExtensions
title Color Map Engine Test 0.1
:: ±±±±±±±±±±±±±±ÛÛÛÛÛÛÛÛÛÛÛ
:: set mapline=mapline
set mapline1=ggggggggggggggggggggggbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggggggggggggg
set mapline2=gggggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggggg
set mapline3=gggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggg
set mapline4=gggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggg
set mapline5=ggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggg
set mapline6=gggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggg
set mapline7=gggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggg
call :initColorPrint
setlocal EnableDelayedExpansion
for /l %%i in (1 1 7) do (
set "line=!mapline%%i!"
set "n=0"
call :loop
echo(
)
call :cleanupColorPrint
pause
exit /b
:loop
if "!line:~%n%,1!"=="" (exit /b) else (
if "!line:~%n%,1!"=="g" (
call :c 0a ±
) else if "!line:~%n%,1!"=="b" (
call :c 1a Û
)
set /a "n+=1"
goto loop
)
%= color engine =%
:: use with: call :c 0a "Text here" /n
:: /n does a new line in the text
:c
:colorPrint Color Str [/n]
if not defined DEL call :initColorPrint
setlocal disableDelayedExpansion
set "s=%~2"
call :colorPrintVar %1 s %3
exit /b
:colorPrintVar Color StrVar [/n]
if not defined DEL call :initColorPrint
setlocal enableDelayedExpansion
pushd .
':
cd \
set "s=!%~2!"
:: The single blank line within the following IN() clause is critical - DO NOT REMOVE
for %%n in (^"^
^") do (
set "s=!s:\=%%~n\%%~n!"
set "s=!s:/=%%~n/%%~n!"
set "s=!s::=%%~n:%%~n!"
)
set "s=!s:"=\"!"
for /f delims^=^ eol^= %%s in ("!s!") do (
if "!" equ "" setlocal disableDelayedExpansion
if %%s==\ (
findstr /a:%~1 "." "\'" nul
<nul set /p "=%DEL%%DEL%%DEL%"
) else if %%s==/ (
findstr /a:%~1 "." "/.\'" nul
<nul set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%"
) else (
findstr /a:%~1 "." "%%s\..\'" nul
<nul set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
)
)
if /i "%~3"=="/n" echo(
popd
exit /b
:initColorPrint
for /f %%A in ('"prompt $H&for %%B in (1) do rem"') do set "DEL=%%A %%A"
<nul >"%temp%\'" set /p "=."
subst ': "%temp%" >nul
exit /b
:cleanupColorPrint
2>nul del "%temp%\'"
>nul subst ': /d
exit /b
Grüße
rubberman (aka aGerman)
Hallo @rubberman,
kann ich grad nicht testen auf dem iPhone. Batch ist natürlich nicht krank, sondern eine der letzten Herausforderungen in unserer langweiligen Zeit, in der Programmiersprachen (fast) immer das tun, was man erwartet
Gruß, Endoro
kann ich grad nicht testen auf dem iPhone. Batch ist natürlich nicht krank, sondern eine der letzten Herausforderungen in unserer langweiligen Zeit, in der Programmiersprachen (fast) immer das tun, was man erwartet
Gruß, Endoro
@Endoro
@130834
Funktionsweise kurz erklärt:
FINDSTR ist keine Built-In Funktion der cmd.exe, sondern ein externes Tool (findstr.exe). Bei jedem Aufruf der Funktion muss also dieser externe Prozess geladen werden. Das dauert nun mal Äonen bei Hunderten von Aufrufen.
Es gibt allerdings etwa elfundneunzigeinhalb 3rd Party Tools für diesen Zweck im Net, weil jeder Zweite der eine Programmiersprache auf Windows lernt, sich irgendwann mal so ein Progrämmchen zusammengeschraubt hat.
Grüße
rubberman
eine der letzten Herausforderungen
Joa, unter Missbrauch von Commands für Dinge für die sie nie gedacht waren und Ausnutzung jedwedem undefinierten Verhaltens. So lange das nur Spielerei ist, ist es OK ...@130834
nur leider ist es immer noch zu langsam
Wird auch nicht schneller.Funktionsweise kurz erklärt:
@echo off &setlocal
::: 1 Grundprinzip :::
:: Datei "x" anlegen, mit einer einzigen Zeile (y in diesem Fall),
:: aber ohne abschließenden Zeilenumbruch, damit ein Backspacing möglich ist.
<nul >"x" set /p "=y"
:: FINDSTR sucht nach y in Datei "x" und dem virtuellen Gerät NUL.
:: Da y nur in "x" gefunden werden kann, wird diese Datei in der mit Option /a
:: angegebenen Farbe markiert. Außerdem wird der gefundene String aus der Datei ausgegeben.
findstr /a:0c "y" "x" nul
:: Da kein Zeilenumbruch geschrieben wurde, wird er per ECHO erzeugt.
echo(
::: 2 Subfolder Parsing :::
:: Der gesamte Pfad wird angezeigt, incl. dem nicht existierenden Unterverzeichnis "text".
:: Das Konstrukt funktioniert, da der Parser erkennt, dass durch .. wieder in das ursprüngliche
:: Verzeichnis zurück gewechselt wird und ignoriert das Subfolder im Pfad. Letzteres sorgt auch
:: dafür, dass die meisten im Dateisystem "verbotenen" Zeichen verwendet werden können.
findstr /a:0c "y" "text mit <>|:*?\..\x" nul
echo(
::: 3 Backspacing im Dateiinhalt :::
:: Diese Schleife extrahiert die Zeichenkombination Backspace-Space-Backspace aus dem eingestellten
:: Kommandozeilenprompt und weist sie der Variablen DEL zu.
for /f "delims=#" %%a in ('"prompt #$H# &for %%b in (1) do rem"') do set "DEL=%%a"
:: Datei "x" wird überschrieben. Diesmal neben dem y, auch mit dem nötigen Backspacing als Inhalt.
<nul >"x" set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%y%DEL%"
:: FINDSTR arbeitet genau wie vorher, nur dass die Ausgabe des Dateiinhaltes nun dafür sorgt,
:: dass alle ungewollten Zeichen von rechts nach links mit Leerzeichen überschrieben werden.
findstr /a:0c "y" "text mit <>|:*?\..\x" nul
:: Da kein Zeilenumbruch erfolgt, kann in derselben Zeile weiter geschrieben werden.
findstr /a:09 "y" " mehr text\..\x" nul
echo(
::: 4 Zeichen \ und / :::
:: Beide Zeichen werden als Trennzeichen im Pfad behandelt und müssen auch so verwendet werden.
:: Mit entsprechendem Backspacing ist es möglich, dass jeweils nur der Backslash oder Slash
:: in der Ausgabe stehen bleiben.
findstr /a:0c "y" "a%DEL%\..\%DEL%%DEL%%DEL%\..\x" nul
findstr /a:09 "y" "a%DEL%/..\%DEL%%DEL%%DEL%\..\x" nul
echo(
::: 5 Anführungszeichen :::
:: Anführungszeichen werden mit einem Backslash maskiert.
findstr /a:0c "y" "\"\..\x" nul
echo(
::: 6 Strings "." und ".." :::
:: Diese Strings werden als "derzeitiges Verzeichnis" bzw. "übergeordnetes Verzeichnis"
:: interpretiert, wenn sie für sich allein stehen. Das lässt dich durch das Voranstellen
:: und Backspacing eines weitern Zeichens verhindern.
findstr /a:0c "y" "a%DEL%.\..\x" nul
findstr /a:09 "y" "a%DEL%..\..\x" nul
echo(
pause
Es gibt allerdings etwa elfundneunzigeinhalb 3rd Party Tools für diesen Zweck im Net, weil jeder Zweite der eine Programmiersprache auf Windows lernt, sich irgendwann mal so ein Progrämmchen zusammengeschraubt hat.
Grüße
rubberman
das würde weniger aufrufe erzeugen.
Klar. Prüfe doch einfach in deiner Schleife, ob ein anderes Zeichen auftaucht.Und eventuell könnte man die color engine noch mehr spezifizieren das es schneller läuft...
Nö. Wie oben schon geschrieben, ist es der Aufruf von findstr.exe, der dich ausbremst. Brauchst du aber, denn dessen Option /a malt deine Farben. Zum Verständnis hatte ich dir noch die paar Zeilen gepostet. Kannst dich gerne selbst daran versuchen. Wenn du meinst, dass der eine oder andere Spezialfall (\/". im String) nicht vorkommt, brauchst du ihn auch nicht zu behandeln.Grüße
rubberman
Du versuchst ja immer noch jedes Zeichen einzeln zu "kolorieren".
Bastel dir doch einfach das Argument für den ctext Aufruf zusammen und rufe das ding nur einmal pro Zeile auf
Bastel dir doch einfach das Argument für den ctext Aufruf zusammen und rufe das ding nur einmal pro Zeile auf
@echo off
mode con cols=90 lines=40
setlocal enabledelayedexpansion enableextensions
setlocal ENABLEDELAYEDEXPANSION
title Color Map Engine Test 1.0
:: striped char: ± full char: Û
:: store the things below in a external TXT to load and manage different Maps ( until the ^^ barrier )
:: set mapline1=ggggggggggggggggggggggbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggggggggggggggggg
:: set mapline2=gggggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggggggggg
:: set mapline3=gggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggggggg
:: set mapline4=gggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggggggg
:: set mapline5=ggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggggggg
:: set mapline6=gggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbgggggggggggggggggggggggggggggggggggggggggg
:: set mapline7=gggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbggggggggggggggggggggggggggggggggggggggg
set mapline1=gbggbbbggbggbbbg
set /a lines=1
:: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for /l %%i in (1 1 %lines%) do (
set "line=!mapline%%i!"
set "n=0"
set "char="
set "arg="
call :loop
ctext.exe "!arg!"
)
ctext.exe "{\n}{07}printed map"
pause >nul
exit /b
:loop
set "newchar=!line:~%n%,1!"
if "%newchar%"=="" (set "arg=!arg!{\n}"&exit /b)
if "%newchar%"=="g" (
if "%newchar%" neq "%char%" set "arg=!arg!{0a}"
set "arg=!arg!±"
) else if "%newchar%"=="b" (
if "%newchar%" neq "%char%" set "arg=!arg!{01}"
set "arg=!arg!Û"
)
set /a "n+=1"
set "char=%newchar%"
goto loop
da ctext.exe den Charakter nicht richtig anzeigt
Jaja, so sind die "Kommandozeilentoolentwickler". Schaffen es nicht ihre Programme vernünftig zu schreiben for /l %%i in (1 1 %lines%) do (
>nul chcp 1252
set "line=!mapline%%i!"
set "n=0"
set "char="
set "arg="
call :loop
>nul chcp 850
ctext.exe "!arg!"
)
Sowie brauche ich \n niemals
Dann schmeiß es raus und es mich echt intressieren würde
Darüber könnte man Bücher schreiben ^^www.c-plusplus.net/forum/161855-full
Kurz: Da der Entwickler des Tools (der auch noch Microsoft MVP ist) nicht ändern kann, wie Windows mit Zeichen umgeht, hätte er es berücksichtigen müssen. Weil er es nicht getan hat, hab ich es gemacht, indem ich mit der Änderung der Codepage (CHCP) die Interpretation der ASCII Werte der Zeichen verändert habe.
Es ist zwar jetzt wieder langsamer
Dann schmeiße diese GOTO Loops raus und arbeite mit FOR /L. Die Zeilenlänge ist ja eh konstant. Und bis zu einer Länge von x (8191 Zeichen für die gesamte Kommandozeile) kannst du das Argument auch komplett für alle Zeilen zusammen basteln, bevor du ctext aufrufst.@echo off
mode con cols=90 lines=40
setlocal enabledelayedexpansion enableextensions
title Color Map Engine Test 1.0
:: striped char: ± full char: Û
:: store the things below in a external TXT to load and manage different Maps ( until the ^^ barrier )
set mapback1=xxxxxxxxxxxxxxxxfffff999999999999999fffffffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set mapback2=xxxxxxxxxxxxxxfff999999999999999999999999999ffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set mapback3=xxxxxxxxxxxxfff99999999999999999999999999999999fffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set mapline1=aaaaaaaaaaaaaaaaaaaaa111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
set mapline2=aaaaaaaaaaaaaaaaa111111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
set mapline3=aaaaaaaaaaaaaaa11111111111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
set /a lines=3
:: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>nul chcp 1252
for /f "tokens=1,3 delims=:" %%i in ('mode con^|findstr /bc:" "^|findstr /n .') do if %%i==2 set /a cols=%%j-1
set "arg="
set "char="
set "back="
for /l %%i in (1 1 %lines%) do (
set "line=!mapline%%i!"
set "bind=!mapback%%i!"
for /l %%j in (0 1 %cols%) do (
set "newchar=!line:~%%j,1!"
set "newback=!bind:~%%j,1!"
if "!newback!" neq "!back!" (
set "arg=!arg!{!newback:x=0!"
set "arg=!arg!!newchar!}"
)
if "!newchar!" neq "!char!" (
set "arg=!arg!{!newback:x=0!"
set "arg=!arg!!newchar!}"
)
if "!newback!" EQU "x" ( set "arg=!arg!Û" ) else ( set "arg=!arg!±" )
set "char=!newchar!"
set "back=!newback!"
)
)
>nul chcp 850
ctext.exe "!arg!"
ctext.exe "{\n}{07}[DEBUG] printed map"
pause >nul
rubberman
Dann musst du zumindest auf zeilenweise Aufrufe zurück rudern.
:: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>nul chcp 1252
set "f=Û"
set "s=±"
>nul chcp 850
for /f "tokens=1,3 delims=:" %%i in ('mode con^|findstr /bc:" "^|findstr /n .') do if %%i==2 set /a cols=%%j-1
for /l %%i in (1 1 %lines%) do (
set "arg="
set "char="
set "back="
set "line=!mapline%%i!"
set "bind=!mapback%%i!"
for /l %%j in (0 1 %cols%) do (
set "newchar=!line:~%%j,1!"
set "newback=!bind:~%%j,1!"
if "!newback!" neq "!back!" (
set "arg=!arg!{!newback:x=0!"
set "arg=!arg!!newchar!}"
)
if "!newchar!" neq "!char!" (
set "arg=!arg!{!newback:x=0!"
set "arg=!arg!!newchar!}"
)
if "!newback!" EQU "x" ( set "arg=!arg!%f%" ) else ( set "arg=!arg!%s%" )
set "char=!newchar!"
set "back=!newback!"
)
ctext.exe "!arg!"
)
ctext.exe "{\n}{07}[DEBUG] printed map"
pause >nul
Also hätte ich ne Firma, würd ich dich sofort einstellen.
*lach* Ich hab meine Karriere schon gemacht. Wenn du mal eine Firma hast, die sich mit der Verarbeitung hochpolymerer Werkstoffe befasst, sag bescheid Selbst wenn mir jemand 'ne Tasse Kaffee für diese Batchspielchen angeboten hat, hab ich das bislang immer abgelehnt. Ich meine, es ist Batch ... da ist das einfach ungerechtfertigt. In Zeiten von PowerShell & Co. umso mehr ^^