Windows batch: echo without new line

后端 未结 18 1415
失恋的感觉
失恋的感觉 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: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 (
      "%$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!"  or 0x1A
    ::
    ::   $write.problemChars - list of characters that cause problems for SET /P
    ::          <0xFF>  
    ::      Note that  and  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   <0xFF>
    )
    exit /b
    

提交回复
热议问题