Windows batch: echo without new line

后端 未结 18 1408
失恋的感觉
失恋的感觉 2020-11-22 04:01

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

相关标签:
18条回答
  • 2020-11-22 04:54

    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.

    0 讨论(0)
  • 2020-11-22 04:55

    DIY cw.exe (console write) utility

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

    Tools

    All you need is .NET installed, which is very common nowadays.

    Materials

    Some characters typed/copy-pasted.

    Steps

    1. Create .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);
            }
        }
    }
    
    1. Run it.

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

    How to use

    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)
    
    0 讨论(0)
  • 2020-11-22 04:55

    I believe there's no such option. Alternatively you can try this

    set text=Hello
    set text=%text% world
    echo %text%
    
    0 讨论(0)
  • 2020-11-22 04:58

    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
    
    0 讨论(0)
  • 2020-11-22 04:58

    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

    0 讨论(0)
  • 2020-11-22 05:00

    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

    0 讨论(0)
提交回复
热议问题