Windows batch: echo without new line

292,112

Solution 1

Using set and the /p parameter you can echo without newline:

C:\> echo Hello World
Hello World

C:\> echo|set /p="Hello World"
Hello World
C:\>

Source

Solution 2

Using: echo | set /p= or <NUL set /p= will both work to suppress the newline.

However, this can be very dangerous when writing more advanced scripts when checking the ERRORLEVEL becomes important as setting set /p= without specifying a variable name will set the ERRORLEVEL to 1.

A better approach would be to just use a dummy variable name like so:
echo | set /p dummyName=Hello World

This will produce exactly what you want without any sneaky stuff going on in the background as I had to find out the hard way, but this only works with the piped version; <NUL set /p dummyName=Hello will still raise the ERRORLEVEL to 1.

Solution 3

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

Solution 4

As an addendum to @xmechanix's answer, I noticed through writing the contents to a file:

echo | set /p dummyName=Hello World > somefile.txt

That this will add an extra space at the end of the printed string, which can be inconvenient, specially since we're trying to avoid adding a new line (another whitespace character) to the end of the string.

Fortunately, quoting the string to be printed, i.e. using:

echo | set /p dummyName="Hello World" > somefile.txt

Will print the string without any newline or space character at the end.

Solution 5

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

Share:
292,112

Related videos on Youtube

gregseth
Author by

gregseth

« Misuse of a tool doesn't mean the tool was designed badly. » twitter: @greg_seth github: github.com/gregseth

Updated on July 20, 2022

Comments

  • gregseth
    gregseth almost 2 years

    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 the same line inside a loop.

    • Patrick Cuff
      Patrick Cuff almost 13 years
    • panny
      panny over 11 years
      this got me nearly crazy..I knew echo could take -n but on the cmd.exe it just wouldn't work^^
    • user66001
      user66001 almost 11 years
      @panny - Despite the common name, echo is not the same command between Windows and Posix. The same as nslookup, it has different options. So the comment "I knew echo could take -n" in the context of a question to do with Windows, is incorrect.
    • Bilbo
      Bilbo over 3 years
      @user66001 - "echoX -n" on Windows is detailed in an answer below posted today.
    • user66001
      user66001 over 3 years
      @Bilbo - Not sure about your use of batch, but 99% of the time I am using it to help automate something for someone else, on not-my-device. Not easy or efficient to supply a batch files with a 3rd party util. (especially if this 3rd party util is the .exe variety, given the virus landscape 7 years on from my original comment).
  • René Nyffenegger
    René Nyffenegger almost 13 years
    This will still print a newline.
  • m0skit0
    m0skit0 almost 13 years
    You can concatenate on the same variable as much as you want and only echo at the very end.
  • m0skit0
    m0skit0 almost 13 years
    Printing it when doing the loop or at the end doesn't matter if the data is preserved. For each loop you just concatenate the data, and then when loop is finished you print it. The result is the same.
  • gregseth
    gregseth almost 13 years
    It does matter if it's an indicator of the progression of the loop.
  • jeb
    jeb almost 13 years
    The pipe is very slow as it creates two extra cmd-tasks, faster is <nul set /p =Hello. set /p can't echo an equal sign as first character nor spaces/tabs.
  • arnep
    arnep over 12 years
    @jeb just for curiosity: do you have any benchmark comparing how much slower my solution is?
  • jeb
    jeb over 12 years
    It's nearly 15 times faster on my system
  • Brian
    Brian almost 12 years
    Add quotes around "Hello World" to prevent the extraneous space after the d.
  • m0skit0
    m0skit0 over 11 years
    You never stated that in your question or requested this behavior anywhere in your question.
  • hakre
    hakre over 11 years
    I also suggest to install git bash. sure it's not the same as gnuwin32 (and it is a goldmine therefore +1), it's just a nice setup, and you have git-bash on the right mouse button nearly everywhere including the start menu button.
  • panny
    panny over 11 years
    can you use tr to just remove the last space character, like in trim?
  • BearCode
    BearCode about 11 years
    use sed for trim: sed -e "s/ *$//"
  • user66001
    user66001 almost 11 years
    @panny - I cannot find a posix/linux util called trim. Also, \r, \n or \r\n (New lines in OSX, Posix and Windows respectively) are not "space" characters.
  • TecBrat
    TecBrat almost 11 years
    I used this along with echoing from a bat file into the clipboard with |clip Clipboard Extender showed me how to do it. echo|set /p=mytext|clip
  • jeb
    jeb over 10 years
    Nice to see a very powerful solution that can handle all characters
  • dbenham
    dbenham over 10 years
    As jeb has stated, SET /P has problems with certain leading characters. I've posted a solution that should work in all cases on all Windows versions from XP onward.
  • CoperNick
    CoperNick about 10 years
    Warning: This will change ERRORLEVEL to 1. See answer by @xmechanix.
  • CoperNick
    CoperNick about 10 years
    Warning: This command will set ERRORLEVEL to 0. If ERRORLEVEL was greater then 0 it will change ERRORLEVEL to 0. This also can be dangerous when writing more advanced scripts. (but +1 for answer)
  • jeb
    jeb almost 10 years
    @user246694 < nul is a redirection from the NUL device. It contains nothing, but that is enough for set /p to stop waiting for user input
  • Pedro
    Pedro over 9 years
    I forgot to tell, it works in Windows 7 It won't work in a command line, only in a batch. For anyone not getting the char, download this example: pecm.com.sapo.pt/SET_with_backspace_char.txt
  • n611x007
    n611x007 almost 9 years
    I'd like to point out that if the computer happens to have network connection to the internet that roughly this much of batch code can be used to download and install python or anything else on the computer which can get you rid of batch. Batch is fun however it's string capabilities are best for weekend challange.
  • raphaelh
    raphaelh almost 9 years
    How do you write the output of <nul set /p =Hello to a file? When I try <nul set /p =Hello >out it hangs...
  • aschipfl
    aschipfl almost 8 years
    The extra space should disappear if you don't put a space between World and >...
  • Joan Bruguera
    Joan Bruguera almost 8 years
    @aschipfl Tried it, it doesn't.
  • Seldom 'Where's Monica' Needy
    Seldom 'Where's Monica' Needy over 7 years
    @jiggunjer You sure? printfing from a Win-7 cmd pane gives me "'printf' is not recognized as an internal or external command, operable program or batch file."
  • kayleeFrye_onDeck
    kayleeFrye_onDeck over 7 years
    printf is not native to windows. This is a windows question.
  • Seldom 'Where's Monica' Needy
    Seldom 'Where's Monica' Needy over 7 years
    @kayleeFrye_onDeck I assume your comment is directed at jiggunjer, not me; I suggest in my question that C and C++ might be used as a fairly platform-independent alternative to shell commands in cases where formatting is important.
  • kayleeFrye_onDeck
    kayleeFrye_onDeck over 7 years
    Forgive me father, for I have skimmed.
  • Rick
    Rick over 7 years
    It doesn't use Unicode encoding even if it's specified.
  • ZEE
    ZEE about 7 years
    weird... and has side effects like errorlevel set... not to mention cpu cycles...
  • Alex
    Alex about 7 years
    But then the input to the shell needs to be parsed correctly. For example, how would such a program print a quotation mark?
  • starfry
    starfry about 7 years
    I found this explanation of this technique. It is important there is no whitespace between the output text and the second pipe.
  • Vlastimil Ovčáčík
    Vlastimil Ovčáčík almost 7 years
    This approach does not work with for cycles, it will only print one line for the whole cycle(s).
  • SilverbackNet
    SilverbackNet over 6 years
    So you basically need an IF ERRORLEVEL==0 (...) ELSE (...) just to not harm your environment in those circumstances. Sheesh.
  • Jonathan
    Jonathan over 6 years
    To clear the errorlevel, cmd /c "exit /b 0" from this article: stackoverflow.com/questions/1113727/… @CoperNick I think your comment extremely valuable.
  • Ben Personick
    Ben Personick over 6 years
    The Quoted variable Method, an undocumented feature of the set command, is generally how I see it should be approached, as it works in all versions of WIndows NT (and 9x if I recall). That is you wrap the Variable name to the end of the value in quotes. This is true for Set/P as well.
  • Ben Personick
    Ben Personick over 6 years
    IE: echo | set /p "dummyName=Hello World" >somefile.txt
  • Ben Personick
    Ben Personick over 6 years
    Also true for Echo
  • Ben Personick
    Ben Personick over 6 years
    Also it should be noted that if you don;t need the variable it can be omitted just line in SET /A
  • Ben Personick
    Ben Personick over 6 years
    IE: echo | set /p "=Hello World" >somefile.txt
  • cdlvcdlv
    cdlvcdlv almost 6 years
    I see this set nl=^& echo. trick everywhere and the name of the variable is misleading. %nl% is not a newline character: it expands to &echo. so in the end you are running a new echo command every time, hence the newline. You can check it out writing echo "%nl%The%nl%new%nl%line%nl%is%nl%not%nl%apparent%nl%througho‌​ut%nl%text%nl%". You get "& echo. The& echo. new& echo. line& echo. is& echo. not& echo. apparent& echo. throughout& echo. text& echo. ", revealing the trick. The output is the same but not for the reasons you suggest.
  • Skip R
    Skip R almost 6 years
    @dbenham on line 6 "echo(" is that functionally the same as "echo." - not seen that before.
  • dbenham
    dbenham almost 6 years
    @SkipR - Yes, it is functionally the same as ECHO., except ECHO. can fail under obscure circumstances. There are a bunch of other forms that can also fail in obscure situations. The only one that always works is ECHO(.
  • Anish
    Anish over 5 years
    I was inspired by your answer and created this little tool with Go and this accompanying task for Azure Pipelines. It just grabs the stdout that is piped in and outputs that in a specific format to be picked up by the build. Thank you!
  • Brent Rittenhouse
    Brent Rittenhouse over 5 years
    ... So, after doing a pretty damn thorough search I haven't found this ANYWHERE on the net. It might be the one time I've actually discovered something, and by dumb luck. For those who don't know you CAN enter control characters if you put your cmd prompt in legacy mode and use the right font. ... But if you simply redirect anything to a file or >con it works too. Seriously. Paste this EXACTLY into your command prompt: "echo ←c◙◙○○ Harharhar!!◙○○ -------------◙◙○○ I am the worst!?:'(○ ♪○NOPE!•♪○ I feel great! Hazzah-le-oop!◙◙○ I am programmeer hear me ... something.◙>con".
  • Brent Rittenhouse
    Brent Rittenhouse over 5 years
    Okay, I hope I found this out before anyone else but ... this is seemingly dependent on not being in a unicode code page. You could store the starting one in a variable do chcp 437, set the set in a variable, or output it, and then switch back (and it should still output). I'm playing around with it still.
  • Brent Rittenhouse
    Brent Rittenhouse over 5 years
    Also, does anyone have any idea why ←c clears the screen?! I can't find an instance of that anywhere on the net. It's specfically that combination, although you seem to be able to have whitespace between the two characters too. For any other character it seems to just.. remove the first character. I don't get it...
  • barlop
    barlop about 5 years
    @aschipfl An extra space will appear if you don't do quotes, and you do a pipe. xxd is a hex dump utility so we see e.g. set /p="abc"<nul|xxd -p displays 616263 whereas set /p=abc<nul|xxd -p gives 61626320
  • aschipfl
    aschipfl about 5 years
    True, @barlop, the quotes prevent trailing spaces to be output, even those inserted by the pipe...
  • subcoder
    subcoder almost 4 years
    Caution: This one passes the leading . and backspace, check the characters at receiving side. They do not show up when received string printed out. So, just for printing out it may not be important but when string is processed then it may cause confusion. Checked in Windows 10.
  • subcoder
    subcoder almost 4 years
    Also, just backspace is fine, it works without any extra character like dot. So, receiver should remove the leading backspace when its required to process string, otherwise when directly printing, receiver should take care that backspace delete one character to the left(when there is not any dot).
  • HaxAddict1337
    HaxAddict1337 almost 4 years
    not only is the 'trick' annoying, ECHO.xxx is actually parsed as a file before it is executed as a command, so it'll fail if there is a file named ECHO in the current directory. Better is echo(
  • gilad905
    gilad905 about 3 years
    well, writing more advanced batch scripts sounds pretty dangerous on its own already :) if not for stable execution, at least risky for the mental state of the writer
  • Alex T
    Alex T almost 3 years
    I know the batch file line "@echo Hello %*, how are you?" would do the same, but the point about "EchoPart.bat" is that it outputs its text without adding a linefeed. This means that you can concatenate texts much like the "cat" command in BASH. Although you wouldn't have to pipe the commands, merely execute them sequentially. In my example tests I ended with a straight echo, but I could have ended with another echoPart.
  • Alex T
    Alex T almost 3 years
    Compare for instance the command lines "dir" and "echopart Local &dir". Spot the difference?
  • Ross Smith II
    Ross Smith II about 2 years
    If you have gnuwin32 (or git) installed, then you can use printf instead of echo. printf does not emit a line feed by default.