Windows批处理:没有换行的echo

gre*_*eth 213 windows cmd newline batch-file

什么是Linux shell命令相当于echo -n在输出结尾处抑制换行符的Linux shell命令?

想法是在循环内写入同一行.

arn*_*nep 222

使用set/p参数可以在没有换行符的情况下回显:

C:\> echo Hello World
Hello World

C:\> echo|set /p="Hello World"
Hello World
C:\>
Run Code Online (Sandbox Code Playgroud)

资源

  • 管道非常慢,因为它创建了两个额外的cmd任务,更快的是`<nul set/p = Hello`.`set/p`不能将等号作为第一个字符或空格/制表符回显. (81认同)
  • 在"Hello World"周围添加引号以防止d后的无关空间. (26认同)
  • 它在我的系统上快了近15倍 (11认同)
  • 警告:这会将ERRORLEVEL更改为1.请参阅@xmechanix的回答. (11认同)
  • @ user246694` <nul`是来自`NUL`设备的重定向.它什么都没有,但这足以让`set/p`停止等待用户输入 (5认同)
  • 正如 jeb 所说,SET /P 在某些前导字符上有问题。我已经发布了 [一个应该适用于所有 Windows 版本的解决方案](http://stackoverflow.com/a/19468559/1012053) 从 XP 开始。 (2认同)

小智 96

使用:echo | set /p=或者<NUL set /p=都可以抑制换行.

但是,在检查ERRORLEVEL变得很重要时编写更高级的脚本会非常危险,因为设置set /p=而不指定变量名称会将ERRORLEVEL设置为1.

更好的方法是使用虚拟变量名称,如下所示:
echo | set /p dummyName=Hello World

这将产生你想要的东西而没有任何偷偷摸摸的东西在后台发生,因为我必须找到困难的方式,但这只适用于管道版本; <NUL set /p dummyName=Hello仍会将ERRORLEVEL提高到1.

  • 警告:此命令将ERRORLEVEL设置为0.如果ERRORLEVEL大于0,则会将ERRORLEVEL更改为0.在编写更高级的脚本时,这也会很危险.(但答案为+1) (19认同)
  • 好吧,编写更高级的批处理脚本本身听起来就已经相当危险了:)如果不是为了稳定的执行,至少对编写者的精神状态有风险 (3认同)
  • 所以你基本上需要一个 IF ERRORLEVEL==0 (...) ELSE (...) 只是为了在这些情况下不损害你的环境。嘘。 (2认同)

dbe*_*ham 27

简单的SET/P方法具有Windows版本之间略有不同的限制.

  • 领先的报价可能会被剥夺

  • 领先的白色空间可能会被剥离

  • 前导=导致语法错误.

有关详细信息,请参阅http://www.dostips.com/forum/viewtopic.php?f=3&t=4209.

jeb发布了一个聪明的解决方案,解决了没有换行的输出文本中的大多数问题,即使是前导空格或=我已经改进了方法,以便它可以在任何版本的Windows上安全地打印绝对任何有效的批处理字符串而无需新行从XP开始.请注意,该:writeInitialize方法包含一个字符串文字,可能无法很好地发布到网站.包括描述字符序列应该是什么的注释.

:write:writeVar方法进行了优化,使得只有含麻烦的前导字符的字符串都使用我的杰布的复制方法的修改后的版本写的.使用更简单,更快速的SET/P方法编写非麻烦的字符串.

@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
Run Code Online (Sandbox Code Playgroud)

  • 很高兴看到一个可以处理所有字符的非常强大的解决方案 (2认同)
  • 我想指出的是,如果计算机碰巧有网络连接到互联网,那么大约这么多的批处理代码可用于在计算机上下载和安装 python 或任何其他可以让您摆脱批处理的东西。批处理很有趣,但它的字符串功能最适合周末挑战。 (2认同)
  • @SkipR - 是的,它在功能上与 `ECHO.` 相同,[除了 `ECHO.` 在不明确的情况下会失败](https://www.dostips.com/forum/viewtopic.php?f=3&amp;t=774 )。还有许多其他形式在晦涩的情况下也可能失败。唯一始终有效的方法是 `ECHO(`. (2认同)

小智 10

作为@ xmechanix答案的附录,我注意到通过将内容写入文件:

echo | set /p dummyName=Hello World > somefile.txt
Run Code Online (Sandbox Code Playgroud)

这将在打印字符串的末尾添加额外的空间,这可能不方便,特别是因为我们试图避免在字符串的末尾添加新行(另一个空白字符).

幸运的是,引用要打印的字符串,即使用:

echo | set /p dummyName="Hello World" > somefile.txt
Run Code Online (Sandbox Code Playgroud)

将打印字符串,最后没有任何换行符或空格字符.

  • 如果你不在"世界"和">"之间放置一个空格,额外的空间就会消失...... (4认同)
  • 即:回声| 设置/p“dummyName=Hello World”&gt;somefile.txt (2认同)
  • @aschipfl如果您不执行引号,而是执行管道,则会出现多余的空格。xxd是一个十六进制转储实用程序,所以我们看到例如`set / p =“ abc” &lt;nul | xxd -p`显示`616263`,而`set / p = abc &lt;nul | xxd -p`给出`61626320` (2认同)

Ped*_*dro 9

SET/P中剥离的空白区域的解决方案:

诀窍是退格char,你可以在文本编辑器EDIT for DOS中召唤.要在EDIT中创建它,请按ctrlP + ctrlH.我会把它粘贴在这里但是这个网页无法显示它.它虽然在记事本上可见(但它很像,一个黑色的小矩形,中间有一个白色的圆圈)

所以你写这个:

<nul set /p=.9    Hello everyone
Run Code Online (Sandbox Code Playgroud)

点可以是任何字符,它只是告诉SET/P文本从那里开始,在空格之前,而不是在" 你好 "." 9 "表示我无法在此显示的退格字符.你必须把它代替9,它将删除" . ",之后你会得到这个:

    Hello Everyone
Run Code Online (Sandbox Code Playgroud)

代替:

Hello Everyone
Run Code Online (Sandbox Code Playgroud)

我希望它有所帮助

  • 我忘了告诉它,它适用于Windows 7它不能在命令行中工作,只能在批处理中工作.对于没有获得char的人,请下载此示例:http://pecm.com.sapo.pt/SET_with_backspace_char.txt (2认同)

Mar*_*ven 8

我根据 @arnep 的想法创建了一个函数:

echo|set /p="你好世界"

这里是:

:SL (sameline)
echo|set /p=%1
exit /b
Run Code Online (Sandbox Code Playgroud)

使用它call :SL "Hello There"
我知道这没什么特别的,但我花了很长时间才想到它,我想我应该把它发布在这里。


Bea*_*ode 7

您可以使用gnuwin32(coreutils包)中的"tr"删除换行符

@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果你正在做大量的脚本编写,gnuwin32就是一个金矿.


Knu*_*ger 5

这是另一种方法,它使用Powershell Write-Host,它具有-NoNewLine参数,将其与之结合使用start /b,它提供了批处理相同的功能.

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
Run Code Online (Sandbox Code Playgroud)

产量

Result 1 - Result 2 - Result 3 - Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

下面的这个稍微不同,不像OP想要的那样工作,但是很有趣,因为每个结果都会覆盖模拟计数器的前一个结果.

@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
Run Code Online (Sandbox Code Playgroud)