What is the Windows batch equivalent of the Linux shell command echo -n
which suppresses the newline at the end of the output?
The idea is to write on t
Maybe this is what your looking for, it's a old school script... :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
or maybe your trying to replace a current line instead of writing to a new line? you can experiment with this by removing the "%bs%" after the "." sign and also by spacing out the other "%bs%" after the "Example message".
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs% Example message %bs%
pause
I find this really interesting because it uses a variable for a purpose other than what it is intended to do. as you can see the "%bs%" represents a backspace. The second "%bs%" uses the backspace to add spaces after the "Example message" to separate the "Pause command's output" without actually adding a visible character after the "Example message". However, this is also possible with a regular percentage sign.
cw.exe
(console write) utilityIf you don't find it out-of-the-box, off-the-shelf, you can DIY. With this cw
utility you can use every kind of characters. At least, I'd like to think so. Please stress-test it and let me know.
All you need is .NET installed, which is very common nowadays.
Some characters typed/copy-pasted.
.bat
file with the following content./* >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);
}
}
}
Run it.
Now you have a nice 4KB utility so you can delete the .bat
.
Alternatively, you can insert this code as a subroutine in any batch, send the resulting .exe
to %temp%
, use it in your batch and delete it when you're done.
If you want write something without new line:
cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".
If you want a carriage return (going to the beginning of the line), run just
cw
So try this from command line:
for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)
I believe there's no such option. Alternatively you can try this
set text=Hello
set text=%text% world
echo %text%
The simple SET /P method has limitations that vary slightly between Windows versions.
Leading quotes may be stripped
Leading white space may be stripped
Leading =
causes a syntax error.
See http://www.dostips.com/forum/viewtopic.php?f=3&t=4209 for more information.
jeb posted a clever solution that solves most of the problems at Output text without linefeed, even with leading space or = I've refined the method so that it can safely print absolutely any valid batch string without the new line, on any version of Windows from XP onward. Note that the :writeInitialize
method contains a string literal that may not post well to the site. A remark is included that describes what the character sequence should be.
The :write
and :writeVar
methods are optimized such that only strings containing troublesome leading characters are written using my modified version of jeb's COPY method. Non-troublesome strings are written using the simpler and faster SET /P method.
@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
Sample 1: This works and produces Exit code = 0. That is Good. Note the "." , directly after echo.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo.| set /p JUNK_VAR=This is a message displayed like Linux echo -n would display it ... & echo %ERRORLEVEL%
This is a message displayed like Linux echo -n would display it ... 0
Sample 2: This works but produces Exit code = 1. That is Bad. Please note the lack of ".", after echo. That appears to be the difference.
C:\Users\phife.dog\gitrepos\1\repo_abc\scripts #
@echo | set /p JUNK_VAR=This is a message displayed like Linux echo -n would display it ... & echo %ERRORLEVEL%
This is a message displayed like Linux echo -n would display it ... 1
A solution for the stripped white space in SET /P:
the trick is that backspace char which you can summon in the text editor EDIT for DOS. To create it in EDIT press ctrlP+ctrlH. I would paste it here but this webpage can't display it. It's visible on Notepad though (it's werid, like a small black rectangle with a white circle in the center)
So you write this:
<nul set /p=.9 Hello everyone
The dot can be any char, it's only there to tell SET /P that the text starts there, before the spaces, and not at the "Hello". The "9" is a representation of the backspace char that I can't display here. You have to put it instead of the 9, and it will delete the "." , after which you'll get this:
Hello Everyone
instead of:
Hello Everyone
I hope it helps