Was ist das Windows-Batch-Äquivalent des Linux-Shell-Befehls echo -n
, der die Zeilenumbrüche am Ende der Ausgabe unterdrückt?
Die Idee ist, innerhalb einer Schleife auf dieselbe Zeile zu schreiben.
Mit set
und dem /p
-Parameter können Sie ohne Zeilenvorschub wiederholen:
C:\> echo Hello World
Hello World
C:\> echo|set /p="Hello World"
Hello World
C:\>
Die Verwendung von: echo | set /p=
oder <NUL set /p=
bewirkt, dass der Zeilenvorschub unterdrückt wird.
Dies kann jedoch sehr gefährlich sein, wenn Sie fortgeschrittenere Skripts schreiben, wenn die Überprüfung von ERRORLEVEL wichtig wird, da durch die Einstellung von set /p=
ohne Angabe eines Variablennamens ERRORLEVEL auf 1 gesetzt wird.
Ein besserer Ansatz wäre, einfach einen Dummy-Variablennamen zu verwenden:echo | set /p dummyName=Hello World
Dies wird genau das produzieren, was Sie wollen, ohne dass hinterlistige Dinge im Hintergrund ablaufen, da ich den harten Weg herausfinden musste. Dies funktioniert jedoch nur mit der Pipe-Version. <NUL set /p dummyName=Hello
erhöht den ERRORLEVEL weiterhin auf 1.
Die einfache SET/P-Methode hat Einschränkungen, die zwischen den Windows-Versionen geringfügig variieren.
Führende Anführungszeichen können entfernt werden
Führende Leerzeichen können entfernt werden
Führender =
verursacht einen Syntaxfehler.
Weitere Informationen finden Sie unter http://www.dostips.com/forum/viewtopic.php?f=3&t=4209 .
jeb hat eine clevere Lösung veröffentlicht, die die meisten Probleme mit löst - Text ohne Zeilenvorschub auch mit führendem Leerzeichen oder = Ich habe die Methode so verfeinert, dass sie absolut jeden gültigen Batch-String ohne die neue Zeile drucken kann jede Windows-Version ab XP. Beachten Sie, dass die :writeInitialize
-Methode ein Zeichenfolgenliteral enthält, das möglicherweise nicht ordnungsgemäß an die Site geschrieben wird. Eine Bemerkung enthält die Beschreibung der Zeichenfolge.
Die :write
- und :writeVar
-Methoden sind so optimiert, dass nur Zeichenfolgen, die störende führende Zeichen enthalten, mit meiner modifizierten Version der COPY-Methode von Jeb geschrieben werden. Nicht lästige Zeichenfolgen werden mit der einfacheren und schnelleren SET/P-Methode geschrieben.
@echo off
setlocal disableDelayedExpansion
call :writeInitialize
call :write "=hello"
call :write " world!%$write.sub%OK!"
echo(
setlocal enableDelayedExpansion
set lf=^
set "str= hello!lf!world^!!!$write.sub!hello!lf!world"
echo(
echo str=!str!
echo(
call :write "str="
call :writeVar str
echo(
exit /b
:write Str
::
:: Write the literal string Str to stdout without a terminating
:: carriage return or line feed. Enclosing quotes are stripped.
::
:: This routine works by calling :writeVar
::
setlocal disableDelayedExpansion
set "str=%~1"
call :writeVar str
exit /b
:writeVar StrVar
::
:: Writes the value of variable StrVar to stdout without a terminating
:: carriage return or line feed.
::
:: The routine relies on variables defined by :writeInitialize. If the
:: variables are not yet defined, then it calls :writeInitialize to
:: temporarily define them. Performance can be improved by explicitly
:: calling :writeInitialize once before the first call to :writeVar
::
if not defined %~1 exit /b
setlocal enableDelayedExpansion
if not defined $write.sub call :writeInitialize
set $write.special=1
if "!%~1:~0,1!" equ "^!" set "$write.special="
for /f delims^=^ eol^= %%A in ("!%~1:~0,1!") do (
if "%%A" neq "=" if "!$write.problemChars:%%A=!" equ "!$write.problemChars!" set "$write.special="
)
if not defined $write.special (
<nul set /p "=!%~1!"
exit /b
)
>"%$write.temp%_1.txt" (echo !str!!$write.sub!)
copy "%$write.temp%_1.txt" /a "%$write.temp%_2.txt" /b >nul
type "%$write.temp%_2.txt"
del "%$write.temp%_1.txt" "%$write.temp%_2.txt"
set "str2=!str:*%$write.sub%=%$write.sub%!"
if "!str2!" neq "!str!" <nul set /p "=!str2!"
exit /b
:writeInitialize
::
:: Defines 3 variables needed by the :write and :writeVar routines
::
:: $write.temp - specifies a base path for temporary files
::
:: $write.sub - contains the SUB character, also known as <CTRL-Z> or 0x1A
::
:: $write.problemChars - list of characters that cause problems for SET /P
:: <carriageReturn> <formFeed> <space> <tab> <0xFF> <equal> <quote>
:: Note that <lineFeed> and <equal> also causes problems, but are handled elsewhere
::
set "$write.temp=%temp%\writeTemp%random%"
copy nul "%$write.temp%.txt" /a >nul
for /f "usebackq" %%A in ("%$write.temp%.txt") do set "$write.sub=%%A"
del "%$write.temp%.txt"
for /f %%A in ('copy /z "%~f0" nul') do for /f %%B in ('cls') do (
set "$write.problemChars=%%A%%B ""
REM the characters after %%B above should be <space> <tab> <0xFF>
)
exit /b
Eine Lösung für das gestrippte Leerzeichen in SET/P:
der Trick ist das Backspace-Zeichen, das Sie im Texteditor EDIT für DOS aufrufen können. Um es in EDIT zu erstellen, drücken Sie ctrlP + ctrlH . Ich würde es hier einfügen, aber diese Webseite kann es nicht anzeigen. Es ist jedoch in Notepad sichtbar (es ist wie ein kleines schwarzes Rechteck mit einem weißen Kreis in der Mitte).
Also schreibst du das:
<nul set /p=.9 Hello everyone
Der Punkt kann ein beliebiges Zeichen sein, es ist nur dazu da, SET/P mitzuteilen, dass der Text dort beginnt, vor den Leerzeichen, und nicht bei "Hello" . Das " 9 " ist a Darstellung des Backspace-Zeichens, das ich hier nicht anzeigen kann. Sie müssen es anstelle der 9 setzen, und es wird das ". " löschen, woraufhin Sie Folgendes erhalten:
Hello Everyone
anstatt:
Hello Everyone
Ich hoffe, es hilft
Als Nachtrag zu @ xmechanixs Antwort habe ich festgestellt, dass ich den Inhalt in eine Datei geschrieben habe:
echo | set /p dummyName=Hello World > somefile.txt
Dass dies ein extra Leerzeichen am Ende der gedruckten Zeichenfolge hinzufügt, was unbequem sein kann, zumal wir versuchen, keine neue Zeile (ein anderes Leerzeichen) am Ende der Zeichenfolge hinzuzufügen.
Glücklicherweise zitiert man die zu druckende Zeichenfolge, d. H.
echo | set /p dummyName="Hello World" > somefile.txt
Druckt den String ohne Zeilen- oder Leerzeichen am Ende.
Sie können die Newline mit "tr" aus gnuwin32 entfernen ( coreutils package)
@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause
Übrigens, wenn Sie viel Scripting machen, ist gnuwin32 eine Goldgrube.
Hier ist eine andere Methode, es verwendet Powershell Write-Host, der einen -NoNewLine-Parameter hat, kombiniert diesen mit start /b
und bietet die gleiche Funktionalität wie Batch.
NoNewLines.cmd
@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - ';Write-Host -NoNewLine 'Result 2 - ';Write-Host -NoNewLine 'Result 3 - '"
PAUSE
Ausgabe
Result 1 - Result 2 - Result 3 - Press any key to continue . . .
Dieses hier ist etwas anders, funktioniert nicht genau wie das OP es will, aber es ist interessant, weil jedes Ergebnis das vorherige Ergebnis überschreibt und einen Zähler emuliert.
@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 2 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 3 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 4 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 5 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 6 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 7 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 8 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 9 - '"
PAUSE
Ab hier
<nul set /p =Testing testing
und auch zu echo beginnend mit Leerzeichen verwenden
echo.Message goes here
cw.exe
(Konsolenschreibprogramm)Wenn Sie es nicht direkt von der Stange finden, können Sie es selbst herstellen. Mit diesem Dienstprogramm cw
können Sie jede Art von Zeichen verwenden. Zumindest würde ich das gerne glauben. Bitte stresstest es und lass es mich wissen.
Alles, was Sie brauchen, ist .NET installiert, was heutzutage sehr verbreitet ist.
Einige Zeichen wurden eingegeben/kopiert.
.bat
-Datei mit folgendem Inhalt./* >nul 2>&1
@echo off
setlocal
set exe=cw
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*csc.exe"') do set "csc=%%v"
"%csc%" -nologo -out:"%exe%.exe" "%~f0"
endlocal
exit /b %errorlevel%
*/
using System;
namespace cw {
class Program {
static void Main() {
var exe = Environment.GetCommandLineArgs()[0];
var rawCmd = Environment.CommandLine;
var line = rawCmd.Remove(rawCmd.IndexOf(exe),exe.Length).TrimStart('"');
line = line.Length < 2 ? "\r" : line.Substring(2) ;
Console.Write(line);
}
}
}
Starte es.
Jetzt haben Sie ein Nice 4KB-Dienstprogramm, mit dem Sie den .bat
löschen können.
Alternativ können Sie diesen Code als Subroutine in einen beliebigen Stapel einfügen, den resultierenden .exe
an %temp%
senden, ihn in Ihrem Stapel verwenden und ihn löschen, wenn Sie fertig sind.
Wenn Sie etwas ohne neue Zeile schreiben wollen:cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".
Wenn Sie einen Wagenrücklauf (bis zum Anfang der Zeile) wünschen, führen Sie ihn einfach auscw
Versuchen Sie es also von der Kommandozeile aus:
for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)
Vielleicht ist es das, wonach Sie suchen, es ist ein altes Schulskript ...: P
set nl=^& echo.
echo %nl%The%nl%new%nl%line%nl%is%nl%not%nl%apparent%nl%throughout%nl%text%nl%
echo only in Prompt.
pause
oder vielleicht versuchen Sie, eine aktuelle Zeile zu ersetzen, anstatt in eine neue Zeile zu schreiben? Vorzeichen und auch durch Platzieren der anderen "% bs%" nach der "Beispielnachricht".
for /f %%a in ('"Prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs% Example message %bs%
pause
Ich finde das wirklich interessant, weil es eine Variable zu einem anderen Zweck verwendet, als es beabsichtigt ist. Wie Sie sehen, steht "% bs%" für eine Rücktaste. Das zweite "% bs%" verwendet die Rücktaste, um nach der "Beispielnachricht" Leerzeichen einzufügen, um die Ausgabe des Befehls "Pause" zu trennen, ohne nach der "Beispielnachricht" tatsächlich ein sichtbares Zeichen hinzuzufügen. Dies ist jedoch auch mit einem normalen Prozentzeichen möglich.
Beispiel 1: Dies funktioniert und erzeugt Exit-Code = 0. Das ist gut. Beachten Sie das "." direkt nach dem Echo.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo. | set/p JUNK_VAR = Dies ist eine Nachricht, die angezeigt wird, als würde das Echo -n von Linux angezeigt ...
Dies ist eine Nachricht, die angezeigt wird, als würde Linux-Echo -n es anzeigen ... 0
Beispiel 2: Dies funktioniert aber erzeugt Exit-Code = 1. Das ist schlecht. Bitte beachten Sie das Fehlen von "." Nach dem Echo. Das scheint der Unterschied zu sein.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@ echo | set/p JUNK_VAR = Dies ist eine Nachricht, die angezeigt wird, als würde das Echo -n von Linux angezeigt ...
Dies ist eine Nachricht, die angezeigt wird, als würde Linux echo -n es anzeigen ... 1
Späte Antwort hier, aber für jeden, der Sonderzeichen in eine einzige Zeile schreiben muss, die die Antwort von dbenham für etwa 80 Zeilen zu lang hält und deren Skripts (möglicherweise aufgrund von Benutzereingaben) unter den Einschränkungen brechen Wenn Sie einfach set /p
verwenden, ist es wahrscheinlich am einfachsten, Ihre .bat oder .cmd-Datei mit einer kompilierten C++ - oder C-Programmdatei zu koppeln und dann nur cout
oder printf
die Zeichen zu verwenden. Auf diese Weise können Sie auch leicht mehrere Male in eine Zeile schreiben, wenn Sie eine Art Fortschrittsbalken oder etwas mit Zeichen anzeigen, wie es anscheinend OP war.
Ich glaube, dass es keine solche Option gibt. Alternativ können Sie dies auch versuchen
set text=Hello
set text=%text% world
echo %text%
Sie können die neue Zeile mit dem Befehl set/p unterdrücken. Der Befehl set/p erkennt kein Leerzeichen. Dafür können Sie einen Punkt und ein Rücktaste-Zeichen verwenden, um es zu erkennen. Sie können eine Variable auch als Speicher verwenden und darin speichern, was Sie drucken möchten, sodass Sie die Variable anstelle des Satzes drucken können. Zum Beispiel:
@echo off
setlocal enabledelayedexpansion
for /f %%a in ('"Prompt $H & for %%b in (1) do rem"') do (set "bs=%%a")
cls
set "var=Hello World! :)"
set "x=0"
:loop
set "display=!var:~%x%,1!"
<nul set /p "print=.%bs%%display%"
ping -n 1 localhost >nul
set /a "x=%x% + 1"
if "!var:~%x%,1!" == "" goto end
goto loop
:end
echo.
pause
exit
Auf diese Weise können Sie alles ohne eine neue Zeile drucken. Ich habe das Programm so erstellt, dass die Zeichen einzeln gedruckt werden, aber Sie können auch Wörter anstelle von Zeichen verwenden, indem Sie die Schleife ändern.
Im obigen Beispiel habe ich "enabledelayedexpansion" verwendet, damit der Befehl set/p "!" Nicht erkennt. Zeichen und druckt stattdessen einen Punkt. Ich hoffe, dass Sie das Ausrufezeichen "!" Nicht verwenden können. ;)
Ich habe aus @arneps Idee eine Funktion gemacht:
echo | set/p = "Hallo Welt"
hier ist es:
:SL (sameline)
echo|set /p=%1
exit /b
Verwenden Sie es mit call :SL "Hello There"
Ich weiß, das ist nichts Besonderes, aber ich habe so lange darüber nachgedacht, dass ich dachte, ich würde es hier posten.