it-swarm.com.de

Windows Batch: Echo ohne neue Zeile

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.

188
gregseth

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:\>

Quelle

197
arnep

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.

85
xmechanix

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
25
dbenham

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

9
Pedro

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.

8
Joan Bruguera

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.

7
BearCode

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
5
Knuckle-Dragger

Ab hier

<nul set /p =Testing testing

und auch zu echo beginnend mit Leerzeichen verwenden

echo.Message goes here

DIY 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.

Werkzeuge

Alles, was Sie brauchen, ist .NET installiert, was heutzutage sehr verbreitet ist.

Materialien

Einige Zeichen wurden eingegeben/kopiert.

Schritte

  1. Erstellen Sie eine .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);
        }
    }
}
  1. Starte es.

  2. 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.

Wie benutzt man

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 aus
cw

Versuchen Sie es also von der Kommandozeile aus:

for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)
2
cdlvcdlv

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. 

2
zask

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 

1
user3175529

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.

0
SeldomNeedy

Ich glaube, dass es keine solche Option gibt. Alternativ können Sie dies auch versuchen

set text=Hello
set text=%text% world
echo %text%
0
m0skit0

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.

0
Mark Deven