ren
Goto Top

Echo ohne Zeilenumbruch und ähnliche Spielereien

Den Befehl ECHO kennt ja jeder. Damit lässt sich einen Zeile, mit ECHO. auch einen leere, auf dem Bildschirm ausgeben. ECHO macht aber auf jeden Fall einen Zeilenumbruch nach dem Text. Dem einen oder anderen ist sicher schon mal der Wunsch aufgekommen, etwas auf den Bildschirm zu schreiben, ohne gleich die Zeile umzubrechen. Auch das ist möglich.

So ohne weiteres käme man wahrscheinlich nicht auf die Idee, dass das mit Hilfe des Befehls SET geht. Genauer mit Hilfe des Befehls SET mit der Option /p. SET weist Variablen Werte zu. /p kann dazu verwendet werden, dass der Benutzer den Wert für die Variable selbst eingeben kann. Syntax:
set /p VARIABLENMANE=TEXT, DEN DER BENUTZER VOR DER EINGABE SEHEN KÖNNEN SOLL
Der Clou: Man kann den Variablennamen einfach weglassen. Der Text wird immer noch ausgegeben, OHNE Zeilenumbruch.
set /p =TEXT, DEN DER BENUTZER VOR DER EINGABE SEHEN KÖNNEN SOLL
Dummerweise wird jetzt immer noch auf eine Eingabe des Benutzers gewartet. Aber dem Problem geht man einfach mit Hilfe der Pipe-Funktion aus dem Weg. Wir müssen sozusagen einen Zeilenumbruch, der als Return gewertet wird, unserem SET-Befehl übergeben.
echo.|set /p =TEXT, DEN DER BENUTZER VOR DER EINGABE SEHEN KÖNNEN SOLL
So, wir haben jetzt ein Echo, das keinen Zeilenumbruch macht. Alternativ geht übrigens auch, einfach NUL dem Befehl mitzugeben.
set /p =TEXT, DEN DER BENUTZER VOR DER EINGABE SEHEN KÖNNEN SOLL<nul
Mit dieser Funktion kann man jetzt lustige, teilweise sinnvolle oder auch weniger sinnvolle Dinge machen:
Wie wäre es mit einem "Schnecken-CLS" (CLS löscht den Bildschirminhalt)
(for /L %i in (1,1,2000) do @set /p = <nul)&cls
Wer es braucht.
Auf diese Art und Weise lässt sich auch ein "Beep" ausgeben, ohne dass die Zeile umgebrochen wird. Wer nicht weiß, dass man in Batch-Dateien überhaupt herumpiepen kann, der lernt jetzt etwas ganz neues:
set /p =•<nul
Dieses • soll das Asci-Zeichen BEEP sein. In meinem Editor kann ich es über Strg+G bekommen, in Notepad++ tut es ein Alt+007 (kann man sich doch merken, oder nicht?) Wie schon geschrieben. Das 7. ASCI-Zeichen ist ein BEEP. Wird das auf die Konsole geschrieben, piept der Rechner. Da es wirklich ein Zeichen ist, wird der Cursor eins weiter geschoben.
set /p =Hello•World<nul
würde also die Ausgabe
Hello World
auf der Konsole erzeugen.

So, dann habe ich noch ein total sinnvolles Feature:
@echo off
call :schreib "Dies ist ein Demotext!" 32100  
:schreib
if not "%2"=="" set /a limit=%2  
if "%2"=="" set /a limit=32000  
if not defined text set text=%~1
if not defined text goto :eof

set /P =%text:~0,1%<nul
:loop1
if %random% LSS %limit% goto :loop1
set text=%text:~1%
if defined text (goto :schreib) else (echo.)
goto :eof
Hintergrund des Ganzen ist wieder das set /p = Text<nul. Es wird Zeichenweise der Text, der übergeben wurde, ausgegeben. Zwischendurch wird eine zufällige Zeit gewartet. Diese Zeit resultiert daraus, dass %random% einen Wert zwischen 1 und 32767 liefert. Je näher man die Zahl, die man :schreib übergeben kann, der 32767 annähert, desto langsamer wird die Ausgabe. Sinnvoll sind Zahlen um die 32000 herum: Je größer die Zahl, desto unregelmäßiger wird es auch.
Übrigens: bei schreib ist mir etwas aufgefallen. Alle Schaltjahre kommt es mal vor, dass scheinbar das <nul nicht funktioniert.

Um das zu verifizieren, habe ich folgendes ebenfalls sehr nützliches Programm geschrieben.
1. lässt es die CPU brennen.
2. sieht es ein wenig nach Matrix aus, und
3. findet es den Fehler in der selbigen gleich. Es bleibt einfach ab und an stehen:
@echo off
color 0A
:matrix
set /a text=%random%
if %text% LSS 10000 <nul set /p = !! 
if %text% LSS 5000 <nul set /p = ##
if %text% LSS 2 <nul set /p =  
if 32766 LSS %text% <nul set /p =  
if 31766 LSS %text% <nul set /p = ??
if 32366 LSS %text% <nul set /p = $$
set /p = %text%<nul
goto :matrix
Diese ulkigen  in Zeile 7 und 8 waren bei mir wieder Piep-Töne (s.o.), damit wird die Ausgabe dann wirklich total unerträglich.
In dem Beispiel sieht man übrigens noch was sinnvolles: ich habe statt set /p = !!<nul einfach <nul set /p = !! genommen. Dann kann man sich den ersten Teil <nul set /p = tatsächlich als echo ohne Zeilenumbruch merken, und einfach in die Zwischenablage kopieren.
Übrigens habe ich auch statt <nul echo.| versucht, um festzustellen, ob auch das nicht immer geht. Und tatsächlich: geht auch nicht, es ist mir aber noch etwas aufgefallen. Mit echo.| ist die Matrix wesentlich langsamer als mit <nul.
Preisfrage: Warum bleibt folgendes Programm nicht stehen?
@echo off
:countsheep
set /a text += 1
set /p = %text%<nul
goto :countsheep
Wie weit kann euer PC zählen?
Für den Schluss habe ich mir noch ein Schmankerl aufgehoben. Hier im Forum wird das Thema hitzig diskutiert. Richtig, es geht um die Fortschrittsanzeige. (Nein, ich möchte keine neue Diskussion darüber losbrechen, ob es möglich ist, den Fortschritt zu bestimmen, ich möchte ihn einfach nur ausgeben)
@echo off & setlocal
::echo Alle Dateien zählen...
for /F "tokens=1" %%a in ('dir *.* ^| findstr "Datei(en)" ') DO (set /a files=%%a)  
::Ende und Anfang malen, das sind 100%
fOR /L %%t IN (1,1,%files%) DO <NUL set /p =-
echo.
::Mach etwas mit jeder Datei und male dabei den Fortschritt
for /F "tokens=1" %%a in ('dir *.* /a-D /b') DO (<NUL set /p =.& type %%a>>muell.txt)  
echo.
endlocal
Diese Batch macht nichts sinnvolles. Sie zählt die Dateien, damit sie weiß, wie weit sie ist, wenn sie mit jeder Datei etwas macht. Dann "kopiert" sie mit Hilfe von type den Text jeder Datei in die Text-Datei muell.txt.

Ich hoffe, das Lesen dieser Anleitung war nicht zu langweilig, vielleicht war ja für den Einen oder Anderen das Eine oder Andere wiederverwendbare dabei.
Gruß
Ren

Content-ID: 102460

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

Printed on: December 5, 2024 at 21:12 o'clock

70620
70620 Nov 24, 2008 at 09:58:47 (UTC)
Goto Top
Schöne Spielerei am Ende, aber insgesamt wars doch hilfreich für mich.
Naja.. erstmal nice to know, aber man weiss ja nie (zuwenig) face-smile

thx
TheUntouchable
TheUntouchable Dec 03, 2008 at 13:19:06 (UTC)
Goto Top
Das mit dem Ausgeben ohne Zeilenumbruch ist wirklich super, ich suche schon seit ewigkeiten nach so einer Möglichkeit! Danke für den Tipp :D
Progfreund
Progfreund Jul 05, 2011 at 09:42:35 (UTC)
Goto Top
Danke für deine Anleitung. face-smile

Ich bin mir bei der Verwendung des Codes nicht ganz sicher.
Warum werden echo. und <nul als return gewertet?
Sind sie quasi nur eine Rückmeldung, die als Return interpretiert wird, sodass
man auch <%TEMP%\Beispiel.txt nehmen könnte?

Welche Variable wird hier unter welchem Namen gesetzt?
set /p = %text%<nul
if %text% LSS 2 <nul set /p =  
if 31766 LSS %text% <nul set /p = ??
Wäre es in deiner Schreibweise auch möglich, set /p "=%text%<nul" mit
Anführungszeichen zu schreiben?

LG
bastla
bastla Jul 05, 2011 at 19:16:53 (UTC)
Goto Top
Hallo Progfreund!
Wäre es in deiner Schreibweise auch möglich, set /p "=%text%<nul" mit
Anführungszeichen zu schreiben?
Du hast es aber mit den Anführungszeichen ... face-wink

Versuch es so:
<nul set /p=""%text%""
Warum werden echo. und <nul als return gewertet?
Da ein "set /p" eine Eingabe erwartet, wird mit "echo." oder der Eingabeumleitung "<" eine solche geliefert; ob Du "Nichts" (nul) oder den Inhalt einer beliebigen Datei dafür verwendest, ist völlig egal, da diese Eingabe ohnehin ignoriert wird - es geht ja nur darum, die Ausgabe zu erzeugen.

Grüße
bastla
timlg07
timlg07 Nov 05, 2016 at 12:54:47 (UTC)
Goto Top
Auch sehr praktisch wenn man etwas in eine Datei schreiben will, ohne einen Zeilenumbruch automatisch einzufügen:

@echo off
set x=0
:loop
set /a x+=1
echo.|set /p =%x%; >> data.dat
goto loop

coole Sache, immer gut zu wissen.
tom1stein
tom1stein Aug 03, 2022 at 08:20:30 (UTC)
Goto Top
Ein Hinweis zur Performance: Eine Pipe "|" erzeugt mehrere tasks und damit ist "echo|set /p" um ca. den Faktor 15 langsamer als simple die Eingabeumlenkung "<nul set /p".