Batch Text animation?
Guten Tag,
ich bin dabei ein batch Programm zu schreiben und nun wollte ich nachfragen ob es möglich ist einen bestimmten Text animiert erscheinen zu lassen (links nach rechts) es würde einfach viel besser aussehen
2 Antworten
demo.cmd
@echo off
for /f "delims=;" %%a in ('"echo prompt $H;|cmd /k"') do set "BS=%%a"
set "string= "hallo huhu" Beispiel Blubb Blubb Blubb"
for /f delims^=^ eol^= %%a in ('"cmd /u /c echo:%string%|find /v """') do (
set/p "=.%BS%%%a" <nul
pathping localhost /q 1 /p 100 >nul
rem Alternative für Pathping: for /l %%. in (1,1,2000) do (call )
)
echo:
pause
Hintergrund der "Geschichte":
cmd /u /c echo: ... startet intern eine neue Instanz von cmd mit UCS-2 le -unterstützung und gibt einen String aus.
- In einem UCS-2-Text wird Zeichen mit einem Wert unter 255 (ASCII-Zeichen) ein 0-wert vorangestellt (aus einem A mit dem 8bit-Hexwert 41 wird damit der 16bit-Hexwert 0041)
- in normalen ASCII-Texten wird ein solcher einfacher 0-Wert jedoch als Stringende angesehen. Damit wird jeder einzelne Buchstabe beim Übergang von unserem "gewaltsam" Erzwungenen 16Bitmodus in den 8bitmodus zu einem eigenen String und auch einzeln der Laufvariable %%a übergeben.
- Umlaute etc funktionieren mit diesem Trick nicht!
Die "Mogelei" mit der Backspacevariable:
- Bei set /p folgt normalerweise nach dem Gleichheitszeichen ein Pronpt (Fragetext) dieser beginnt am linken Rand einer Zeile oder am ende des vorherigen Strings (wenn kein Zeilenvorschub erfolgte) und duldet keine Leerzeichen am Anfang. das kann man verhindern indem ein anderes Zeichen (Punkt) an den Anfang schreibt
set/p "= Text" <nul &rem Leerzeichen werden Entfernt
set/p "=. Text" <nul &rem Leerzeichen bleiben erhalten
- Nur muss man den Punkt wieder Loswerden. Das macht ein Backspace-Zeichen (ASCII 08) (Rückwärtslöschen)
- Das Backspace läst sich jedoch nicht mit der Tastatur in einen Code eingeben und speichern, also muss man es in Batch wieder mal mit einem Trick erzeugen. ...und in der %BS% Variable speichern.
Im Gegensatz zu ping hat pathping eine Granularität von Millisekunden.
Sollte pathping nicht funktionieren, kannst du ersatzweise eine Bremsschleife verwenden
for /l %%. in (1,1,2000) do (call ) &rem 2000 ist die Anzahl der Leerläufe nichts wird getan
... das war die Einfache variante... jetz lasse ich meine Show laufen:
gosttyper_color.cmd
@echo off
chcp 65001 >nul
setlocal enableDelayedExpansion
call :initAnsi
call :initMacro
rem Farbtabelle für den Regenbogen definieren
set "Regenbogen=,52,88,124,160,196,202,208,214,220,226,190,154,118,82,46,41,36,31,26,21,20,55,53,"
rem Regenbogen Spiegeln (letzte Farbe zuerst) (auch Variablennamen unterliegen der Kreativität XD)
for %%a in (%Regenbogen%) do (set "negobnegeR=,%%a!negobnegeR!")
rem mach nen Schmetteling draus
set "RegenbogenBfly=%Regenbogen%%negobnegeR%"
set "ShadesOfGray=237 238 239 240 241 242 243 244 245 246 247 248 249"
for %%a in (%ShadesOfGray%) do (set "notShadesOfGray=,%%a!notShadesOfGray%!")
rem mach nen Schmetteling draus
set "SoGrayBfly=%ShadesOfGray%%notShadesOfGray%"
set "NightBlue=17"
set "OrangeWave=202 208 214 220 214 208"
rem initilisiere für die angegebene Farbtabelle jeweils ein Array mit den Escape seqenzen für
rem Hintergrund Fabtabelle.B und Vordergrund Fabtabelle.F
for %%a in (RegenbogenBfly , ShadesOfGray , SoGrayBfly , NightBlue , OrangeWave) do ( call :initANSI_ColorArray %%~a)
)
rem Aufruf: verzögerung FarbeTabelleB/F ode =für Default "Text "
%#__gostType% 0 NightBlue.B ".so geht man mit ""Gänsefüßchen"" & $$ um und ..."
%#__gostType% 0 NightBlue.B "... so macht man ein Ausrufezeichen $x ....."
%#__gostType% 0 NightBlue.B """..?.+.*.~.§.@.µ.€.|.<.>.&.=.$p.$x.$$..........."""
%#__gostType% 2000 OrangeWave.F "...$$x=$x.,.$$p=$p.,.$$$=$$.,.""""="".................."
%#__gostType% 2000 OrangeWave.b "...$$x=$x.,.$$p=$p.,.$$$=$$.,.""""="".................."
%#__gostType% 2000 = "......................I......................."
%#__gostType% 2000 = "....................like......................"
%#__gostType% 2000 = "..................Scripting. ................."
%#__gostType% 0 RegenbogenBfly.B "......................I......................."
%#__gostType% 1000 RegenbogenBfly.B "....................like......................"
%#__gostType% 4000 RegenbogenBfly.B "..............Background Colors..............."
%#__gostType% 8000 SoGrayBfly.B ".............. some Gray ..............."
%#__gostType% 2000 RegenbogenBfly.F "......................I......................."
%#__gostType% 2000 RegenbogenBfly.F "....................like......................"
%#__gostType% 2000 RegenbogenBfly.F "..............Foreground Colors..............."
%#__gostType% 20000 ShadesOfGray.F ".............. more Gray ..............."
echo ende...
pause
exit /b
:::::: Helper Routines ::::::
:initANSI_ColorArray %1 VarName Colortable
set ".cIndex=0"
for %%a in (!%1!) do (
rem Arrays mit Farbsequenzen anlegen BackGround und ForeGround
set "CArray.%1.F.!.cIndex!=%ESC%[38;5;%%am"
set "CArray.%1.B.!.cIndex!=%ESC%[48;5;%%am"
set /a ".cIndex+=1"
)
set "%1.F.cIndex=%.cIndex%"
set "%1.B.cIndex=%.cIndex%"
exit /b
:initMacro
rem als estes wird der else-Zweig aufgelöst beim aufruf des Macros folgen die Argumente dem set argv=
rem im zweiten Schritt wird argv aufgelöst und die belegten Variablen getunnelt (wegen evt Sonderzeichen)
set #__gostType=for %%. in (1 2) do^
if %%.==2 (^
for /f "tokens=1,2*" %%a in ("^!argv^!") do (^
set __StringToSplit=%%~c^&^
call :draw __StringToSplit %%~a %%~b^
)^
) else set argv=
exit /b
:initAnsi
rem prüfe ob Escape-Sequenzen erlaubt sind (Windows 10 v1903)
rem nur der !!!DWord!!!-Wert ForceV2=0 deaktiviert, alles andere erlaubt Escapesequenzen (ansonsten scheinen ANSISequenzen inzwischen by default unterstützt zu werden)
for /f "tokens=3 delims=." %%a in ('ver') do (
if %%a geq 18362 (reg query "HKCU\Console" /v "ForceV2"|find "REG_DWORD 0x0">nul && (
echo Neue Consolenfunktionen sind ausgeschaltet!) || goto :initAnsiVars
) else ( echo Benötige Windows 10 ab Version 1903)
)
timeout 5 >nul
exit /b
)
:initAnsiVars
rem erzeuge ESC-Zeichen (ASCII 27)
for /f %%. in ('"echo prompt $E|cmd"') do set "ESC=%%."
rem Cursormacros:
set "saveCursorPos=%ESC%7"
set "loadCursorPos=%ESC%8"
set "CursOff=%ESC%[?25l"
set "CursOn=%ESC%[?25h"
set "resetColor=%ESC%[0m"
rem Cursor unsichtbar machen
echo %saveCursorPos%%CursOff%
exit /b
:::::: subroutines :::::
:draw
set "lastColorIndex=-1
set "%~1=!%~1:""="!"
rem Stringlänge-1 ermitteln
@(echo !%~1!)>"%temp%\%~n0.len"
for %%a in ("%temp%\%~n0.len?") do set /a "%~1.maxIndex=%%~za-3"
for /l %%. in (0,1,!%~1.maxIndex!) do (
set Char=!char!!%~1:~%%.,1!
rem kommt ein Platzhalter:
if "!char!" neq "$" (
rem für ein Ausrufezeichen?
if /i "!char!"=="$X" set "char=^!"
if /i "!char!"=="$P" set "char=%%"
if "!char!"=="$$" set "char=$"
set /a "lastColorIndex+=1 , __cNr=lastColorIndex %% %3.cIndex" 2>nul
rem Fabnummer in den als Laufvariable in den Arrayindex mogeln... (!array!index !! geht nicht)
for %%. in ("!__cNr!") do (
echo:%loadCursorPos%!CArray.%~3.%%~.!!char!%saveCursorPos%
)
rem Bremsschleife
for /l %%. in (1,1,%~2) do (call)
set "char="
)
)
echo:%resetColor%%saveCursorPos%
exit /b
...wie's Funktioniert? alles im Code Kommentiert 😅 (sonst wäre ich beim schreiben Irre geworden 😵)
So schön das alles ist. Textausgabe in Batch kann nur mit jeder Menge Tricks beherscht werden. steck nicht allzuviel Energie in einen strebenden Gaul. Batch hat nicht mehr viel Zukunft.
Ich empfehle Dir auf Powershell umzusatteln, bevor Batch Dir das Hirn wegbrutzelt.
Obige Demo in powershell:
Demo.ps1
$Text=' "hallo huhu" Beispiel Blubb Blubb Blubb'
$Text -split $Null| ForEach-Object {
Write-Host $_ -NoNewline
Start-Sleep -Milliseconds 50
}
''
pause
..das geht aber auch kurz und schmerzlos:
' "hallo huhu" Beispiel Blubb Blubb Blubb'-split ''|%{Write-Host $_ -n;sleep -m 50}
Hallo,
Ja klar, es ist möglich, in einem Batch-Programm Text animiert von links nach rechts erscheinen zu lassen, indem Du einfach Zeichen des Texts nacheinander ausgibst.
zum beispel:
@echo off
setlocal enabledelayedexpansion
:: Text, der animiert angezeigt werden soll
set "text=Hallo, Welt!"
(für Hallo, Welt! gibst du dann deinen text ein)
:: Jedes Zeichen des Texts nacheinander anzeigen
for /l %%i in (0,1,%stringlength%) do (
call echo|set /p=!text:~%%i,1!
ping localhost -n 2 > nul
)
echo.
pause
Hierbei wird die ping-Anweisung als Ersatz für einen Sleep-Befehl verwendet, um eine kurze Verzögerung zwischen dem Anzeigen jedes Zeichens zu erzeugen. Es gibt viele verschiedene Wege, um in einem Batch-Script eine Pause einzulegen, aber ping ist ein einfacher Trick, der oft verwendet wird.
Du kannst auch effekte wie Einblendeffekt, Laufschrift oder einen blinkenden text programmieren, ist natürlich etwas komplexer aber machbar
ping localhost -n 2 > nul oder einfach ping -n 2 > nul wartet in etwa 2 Sekunden (-n 2) und führt die Batchdatei dann weiter aus. Das kannst du dann so lange einstellen wie du willst. Ich weiß gar nicht ob es da eine Grenze gibt
Das war ein Beispielcode du irsel. Hat bei mir funktioniert. Er hätte es nur umändern müssen
@echo off
setlocal enabledelayedexpansion
:: Text, der animiert angezeigt werden soll
set "text=Hallo, Welt!"
:: Länge des Texts berechnen
set "length=0"
for /l %%A in (12,-1,0) do (
set /a "length|=1<<%%A"
for %%B in (!length!) do if "!text:~%%B,1!"=="" set /a "length&=~1<<%%A"
)
:: Jedes Zeichen des Texts nacheinander anzeigen
for /l %%i in (0,1,!length!) do (
if "!text:~%%i,1!"==" " (
<nul set /p "= "
) else (
<nul set /p=!text:~%%i,1!
)
ping localhost -n 2 > nul
)
echo.
pause
- Die Stringlänge wird berechnet, indem die Bit-Shift-Technik verwendet wird, um die maximale Länge des Strings zu ermitteln.
- Bei der Verarbeitung von Leerzeichen wird
<nul set /p "= "
verwendet, um Leerzeichen korrekt zu behandeln.
3.Der Input
<nul
ersetzt den
echo
-Teil, um die Ausgabe ohne Zeilenumbruch zu erzeugen.
Bist du Du dir sicher , das Deine Length-Methode den richtigen Wert ausgibt.
Hallo, Welt! hat 12 Zeichen! Deine Methode liefert 11.
Du musst mir nichts erklären , ich weiß selbst wo bei Dir der Hase im Pfeffer liegt. (die Methode rechnet schon richtig, aber benötigt "setlocal enabledelayedexpansion" und frist dadurch Ausrufezeichen. Deshalb würde ich mal sagen unzweckmäßig! Zudem ist die Methode wie Du sie konzipiert hast Laaangsam.
Das geht viel bequemer:
for /f "skip=1 delims=:" %%a in ('"(echo:%text%&echo:)|findstr /o $"') do set /a "length=%%a-3"
...ist aber auch nicht das Rennpferd.
Das schnellste (solange man nicht mit einem Diskettenlaufwerk arbeitet) ist einfach das schreiben des Textes in eine temporäre Datei und ermitteln der Dateigröße (minus Schutzquotes und Zeilenvorschub)
echo "%Text%">"%temp%\strLen.tmp"
for /f "tokens=*" %%a in ("%temp%\strLen.tmp") do set /a "length=%%~za - 4"
echo %length%
Bei der Verarbeitung von Leerzeichen wird <nul set /p "= "
verwendet, um Leerzeichen korrekt zu behandeln.
Nö geht nicht...
Das soll geschrieben werden:
Hallo, Welt!
Und das wird geschrieben:
Hallo,Welt
Hat bei mir funktioniert.
Wenn Du das verschlucken von Zeichen als korrekte Funktion tolerierst?
Sorry ich kanns mir nicht verkneifen : wenn du als Feuerwehrmann oder Sanitäter genauso "tolerant" arbeitest, würde ich im Ernstfall dann doch lieber auf Deine Anwesenheit verzichten 🤪
Ok, mir musst Du nichts über Batch erzählen.
Du Vergleichst Notfallmedizin mit programmieren. Ist ja genau so wie Äpfel mit Birnen zu vergleichen. Das zeigt ja schon alles über dich...
Muss ich jetzt einfach so sagen : So Leute wie dich würde ich auch nicht gerne behandeln wollen. Das sind dann meistens die Leute, die mir was erzählen wollen, wenn wir 10 Minuten brauchen weil kein anderer rtw im Umkreis ist.
Nur weil du dich jetzt schlauer machen musst und dich in den Vordergrund stellen willst 😂😂. Was willst du mir denn erzählen?
Mein Code funktioniert wenn auch langsam. Für seine "privaten Zwecke" reicht es Herr Professor, Sorry!
Wie du deinen Rang als Experte mit so einer Art bekommen hast wundert mich auch.
Gut aber das Gute frage Team macht eben auch mal Fehler ☠️
Ist ja genau so wie Äpfel mit Birnen zu vergleichen.
Du irrst... Wenn man eine Arbeit verrichtet, gleich welche, dann exakt.
Ich habe die Steuerung für eine chemische Industrieanlage entwickelt, da gibts keine Fehlertoleranz. PI mal Daumen oder wie Du es auszudrücken pflegst "privaten Zwecke" und so eine Anlage fliegt in die Luft (mit allen Folgen)
Expertise erreicht man nicht für lobhudelei sondern auch dafür das man sich Kritik stellen kann und Lehren zieht und den Arsch in der Hose hat auch Kritik zu üben!
Hast Du mal probiert ob Dein Code Funktioniert?
geht natürlich nicht!
..wo hast Du %stringlength% definiert? (...und wie ermittelst Du die Länge eines Strings in Batch?) ...und wie gehst Du mit Leerzeichen im Text um (die werde von set/p gefressen)? weshalb call echo mit pipe, stat nul-Input?
prima falsch abgeschrieben! Applaus.