Linux批处理命令echo -n的Windows批处理等效于什么,该命令在输出末尾禁止换行符? />

评论

参见[stackoverflow.com/questions/245395/…[1]:stackoverflow.com/questions/245395/…

这让我几乎疯了..我知道echo可能会占用-n,但在cmd.exe上它根本无法工作^^

@panny-尽管使用了通用名称,但Windows和Posix之间的echo命令并不相同。与nslookup一样,它具有不同的选项。因此,在与Windows有关的问题中,“我知道echo可以使用-n”的注释是错误的。

@ user66001-Windows下的“ echoX -n”在下面今天发布的答案中进行了详细说明。

@Bilbo-不确定您是否使用批处理,但是我有99%的时间在非我的设备上使用它来帮助其他人实现自动化。用第三方工具提供批处理文件并不容易或效率很高。 (特别是如果此第3方util是.exe变体,考虑到从我最初的评论开始算起的病毒情况已有7年之久了。)

#1 楼

使用set/p参数,您可以不使用换行符进行回显:

C:\> echo Hello World
Hello World

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




评论


管道非常缓慢,因为它创建了两个额外的cmd任务,速度更快
–杰布
11年8月18日在18:23



在我的系统上快了将近15倍

–杰布
11年8月22日在16:58

在“ Hello World”周围添加引号,以防止d之后出现多余的空格。

–布赖恩
2012年5月31日19:45

警告:这会将ERRORLEVEL更改为1。请参阅@xmechanix的回答。

–CoperNick
2014年5月12日14:21

@ user246694
–杰布
2014年7月17日下午5:53

#2 楼

使用:echo | set /p=<NUL set /p=都可以抑制换行符。

但是,当检查ERRORLEVEL变得很重要时编写更高级的脚本时,这非常危险,因为设置set /p=而不指定变量名将设置换行符。 ERRORLEVEL到1。

更好的方法是只使用一个虚拟变量名称,如下所示:我不得不找出困难的背景,但这仅适用于管道版本; echo | set /p dummyName=Hello World仍会将ERRORLEVEL提高到1。

评论


警告:此命令会将ERRORLEVEL设置为0。如果ERRORLEVEL大于0,它将ERRORLEVEL更改为0。这在编写更高级的脚本时也很危险。 (但+1为答案)

–CoperNick
2014年5月13日在7:42

因此,您基本上需要一个IF ERRORLEVEL == 0(...)ELSE(...),以便在这种情况下不损害您的环境。嘘。

– SilverbackNet
17-09-22在0:33

#3 楼

简单的SET / P方法的局限性在Windows版本之间略有不同。


领先的报价可能会被删除
领先的空白可能会被删除
领先的=导致语法错误。

有关更多信息,请参见http://www.dostips.com/forum/viewtopic.php?f=3&t=4209。

jeb发布了一个巧妙的解决方案可以解决没有换行符的输出文本中的大多数问题,即使有前导空格或=我也改进了该方法,以便在XP以后的任何Windows版本上,它都可以安全地打印没有换行的任何有效批处理字符串。请注意,:writeInitialize方法包含一个字符串文字,可能无法很好地发布到站点。其中包括一个说明字符序列的注释。

:write:writeVar方法进行了优化,以便使用我的修改版的jeb COPY方法仅写入包含麻烦的前导字符的字符串。使用更简单,更快速的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


评论


很高兴看到一个可以处理所有字符的强大解决方案

–杰布
13-10-19在17:16

我想指出的是,如果计算机恰好与互联网建立了网络连接,则大约可以使用这么多的批处理代码来下载并安装python或计算机上的其他任何可以摆脱批处理的代码。批处理很有趣,但是它的字符串功能最适合周末挑战。

–n611x007
2015年7月9日在11:12

第6行“ echo(”)中的@dbenham在功能上与“ echo。”相同-之前从未见过。

–跳过R
18年8月11日在2:17

@SkipR-是的,除了ECHO之外,它在功能上与ECHO。相同。在晦涩的情况下可能会失败。还有许多其他形式也可能在晦涩的情况下失败。始终有效的唯一方法是ECHO(。

– dbenham
18年8月11日在4:09

#4 楼

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

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


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

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

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


将打印字符串,结尾没有任何换行符或空格字符。

评论


如果您未在World和> ...之间放置空格,则多余的空格应消失。

– aschipfl
16年7月23日在0:58

@aschipfl尝试过,没有。

–琼·布鲁格拉(Joan Bruguera)
16年7月25日在7:07

引用变量方法是set命令未记录的功能,通常是我认为应采用的方法,因为它可用于所有版本的Windows NT(如果我还记得,则为9x)。也就是说,将变量名包装在引号中值的末尾。 Set / P也是如此。

– Ben Personick
17-10-24在14:51

IE:echo |设置/ p“ dummyName = Hello World”> somefile.txt

– Ben Personick
17-10-24在14:51

@aschipfl如果您不执行引号而执行管道,则会出现一个多余的空格。 xxd是一个十六进制转储实用程序,因此我们看到例如set / p =“ abc”
– barlop
19 Mar 10 '19在4:33



#5 楼

解决SET / P中带空格的解决方案:诀窍是可以在文本编辑器DOS编辑器中调用退格字符。要在EDIT中创建它,请按ctrlP + ctrlH。
我将其粘贴到此处,但此网页无法显示。尽管它在记事本上可见(它很弯曲,就像一个小的黑色矩形,中间有一个白色圆圈)

所以您这样写:

<nul set /p=.9    Hello everyone
/>点可以是任何字符,只能告诉SET / P文本从空格开始,而不是在“ Hello”处开始。
“ 9”表示退格char我不能在这里显示。您必须输入而不是9,它将删除“。”。 ,之后您将得到:

    Hello Everyone


评论


我忘了告诉大家,它在Windows 7中有效。它将不能在命令行中有效,而只能在批处理中有效。对于没有获取字符的任何人,请下载以下示例:pecm.com.sapo.pt/SET_with_backspace_char.txt

–佩德罗(Pedro)
2015年1月25日在21:43



对于Echo也是如此

– Ben Personick
17-10-24在14:55

...因此,在进行了非常可恶的彻底搜索之后,我在网上找不到任何地方。也许这是我一次真正地发现一些东西的过程,但那真是愚蠢。对于那些不知道您的人,如果您将cmd提示符置于传统模式并使用正确的字体,则可以输入控制字符。 ...但是,如果您只是将任何内容重定向到文件或> con,它也可以工作。说真的将此内容完全粘贴到您的命令提示符中:“ echo←c◙◙○○Harharhar !!◙○○-------------◙◙○○我最糟糕!?::'(○♪ ○NOPE!•♪○我感觉很棒!Hazzah-le-oop!◙◙○我是编程人员,听到我的声音……...。con。

–布伦特·里滕豪斯(Brent Rittenhouse)
19年2月16日在3:11

好的,我希望我能在其他任何人之前找到它,但是...这似乎取决于不在unicode代码页中。您可以将起始文件存储在do chcp 437变量中,在变量中设置集,或输出它,然后切回(它仍应输出)。我还在玩它。

–布伦特·里滕豪斯(Brent Rittenhouse)
19年2月16日在4:32

另外,没有人知道为什么←c清除屏幕吗?我在网上的任何地方都找不到该实例。显然是这种组合,尽管您似乎也可以在两个字符之间留有空格。对于任何其他字符,似乎只是..删除第一个字符。我不明白...

–布伦特·里滕豪斯(Brent Rittenhouse)
19年2月16日在4:33

#6 楼

您可以从gnuwin32(coreutils程序包)中使用“ tr”删除换行符。

@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause


顺便说一句,如果您要编写大量脚本,gnuwin32是金矿。 br />

评论


我也建议安装git bash。确保它与gnuwin32不同(它是金矿,因此为+1),这只是一个不错的设置,并且几乎在所有地方(包括开始菜单按钮)的鼠标右键都具有git-bash。

– hakre
13年1月26日在21:48



您可以使用tr来删除最后一个空格字符吗?

–panny
13年2月13日在12:50

使用sed进行修整:sed -e“ s / * $ //”

– BearCode
13年5月5日在23:44

@panny-我找不到名为trim的posix / linux util。同样,\ r,\ n或\ r \ n(分别在OSX,Posix和Windows中换行)也不是“空格”字符。

–user66001
2013年6月3日18:11



#7 楼

这是另一种方法,它使用具有-NoNewLine参数的Powershell Write-Host,并将其与start /b结合使用,并从批处理中提供相同的功能。
@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - ';Write-Host -NoNewLine 'Result 2 - ';Write-Host -NoNewLine 'Result 3 - '"
PAUSE


输出

Result 1 - Result 2 - Result 3 - Press any key to continue . . .


下面的内容略有不同,不能完全按照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


#8 楼


从这里


<nul set /p =Testing testing


也可以从空格开始回声使用

echo.Message goes here


#9 楼

我根据@arnep的想法制作了一个函数:


echo | set / p =“ Hello World”


这里是:

:SL (sameline)
echo|set /p=%1
exit /b


call :SL "Hello There"一起使用
我知道这没什么特别的,但是花了我很长时间才想到,我想我会把它张贴在这里。

#10 楼

也许这是您想要的,这是一个古老的脚本...: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


,或者您尝试替换当前行而不是写新行行吗?
您可以通过删除“”之后的“%bs%”来进行实验。签名,并在“示例消息”后面加上其他“%bs%”。

for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs%         Example message         %bs%
pause


我发现这真的很有趣,因为它出于目的使用变量除了打算做什么。如您所见,“%bs%”表示退格键。第二个“%bs%”使用空格在“示例消息”之后添加空格以分隔“暂停命令的输出”,而没有实际在“示例消息”之后添加可见字符。但是,使用常规百分号也是可能的。

评论


我看到这个集合nl = ^&echo。到处都是把戏,变量名令人误解。 %nl%不是换行符:它将扩展为&echo。因此最终您每次都会运行一个新的echo命令,因此将换行。您可以写出echo“%nl%The%nl%new%nl%line%nl%is%nl%not%nl%apparent%nl%throughout%nl%text%nl%”进行检查。您将得到“&回声。&&回声。new&回声。line&回声。is&回声。not&回声。表观&回声。输出是相同的,但并非出于您建议的原因。

– cdlvcdlv
18年7月16日在9:25



不仅“技巧”令人讨厌,ECHO.xxx实际上在作为命令执行之前已被解析为文件,因此,如果当前目录中存在名为ECHO的文件,它将失败。更好的是echo(

–HackingAddict1337
7月19日10:30



#11 楼

示例1:这有效并产生退出代码=0。很好。
注意“。” ,直接在echo之后。


C:\ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts#
@echo。| set / p JUNK_VAR =这是一条类似Linux echo -n会显示的消息...&echo%ERRORLEVEL%


这是一条类似Linux echo -n会显示的消息它... 0

示例2:可以工作,但是会产生退出代码=1。这很糟糕。
回声后请注意缺少“。”。



C:\ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts#
@echo | set / p JUNK_VAR =这是一条类似Linux echo -n会显示的消息...&echo%ERRORLEVEL%


这是一条类似Linux echo -n会显示的消息它... 1

#12 楼

DIY cw.exe(控制台写入)实用程序

如果您没有开箱即用的现成工具,则可以DIY。使用此cw实用程序,您可以使用各种字符。至少,我想这样。请对其进行压力测试,让我知道。

工具

您所需要的只是安装了.NET,这在当今非常普遍。

材料

键入/复制粘贴了某些字符。

步骤


创建具有以下内容的.bat文件。

/* >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);
        }
    }
}



运行它。
现在有了一个不错的4KB实用程序,因此您可以删除.bat

也可以插入将此代码作为任何批处理的子例程,将生成的.exe发送到%temp%,在批处理中使用它,并在完成后将其删除。

如何使用

如果您想写一些没有换行的东西:cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".

如果要回车(转到行的开头),只需运行cw

,所以从命令行尝试:

for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)


评论


您的回答启发了我,并使用Go和Azure Pipelines的随附任务创建了这个小工具。它只是获取输入的标准输出,并以特定格式输出以供构建使用。谢谢!

–riezebosch
18年11月14日在20:06

#13 楼

受此问题答案的启发,我制作了一个简单的计数器批处理脚本,该脚本始终在同一行上打印进度值(0-100%)(覆盖上一个)。

备注:*是不可打印的字符,应使用[Alt + Numpad 0 + Numpad 8]组合键输入,这是backspace字符。

@ECHO OFF

FOR /L %%A in (0, 10, 100) DO (     
    ECHO|SET /P="****%%A%%"    
    CALL:Wait 1
)

GOTO:EOF

:Wait
SET /A "delay=%~1+1"
CALL PING 127.0.0.1 -n %delay% > NUL
GOTO:EOF


#14 楼

您可以使用set / p命令取消换行。 set / p命令不能识别空格,因为您可以使用点和退格字符使其识别。您还可以将变量用作存储器并在其中存储要打印的内容,以便可以打印变量而不是句子。例如:

@echo off
setlocal enabledelayedexpansion
for /f %%a in ('"prompt $H & for %%b in (1) do rem"') do (set "bs=%%a")
cls
set "var=Hello World! :)"
set "x=0"

:loop
set "display=!var:~%x%,1!"
<nul set /p "print=.%bs%%display%"
ping -n 1 localhost >nul
set /a "x=%x% + 1"
if "!var:~%x%,1!" == "" goto end
goto loop

:end
echo.
pause
exit


这样,您可以打印任何内容而无需换行。我已经制作了程序来逐个打印字符,但是您也可以通过更改循环来使用单词代替字符。

在上面的示例中,我使用了“ enabledelayedexpansion”,因此set / p命令无法识别“!”字符并打印一个点代替它。希望您不要使用感叹号“!” ;)

#15 楼

我相信没有这样的选择。另外,您也可以尝试一下

set text=Hello
set text=%text% world
echo %text%


评论


这仍然会打印换行符。

–RenéNyffenegger
11年8月18日在10:18

您可以根据需要连接多个变量,并且只在最后回显。

–m0skit0
11年8月18日在10:24



在执行循环时或结束时打印该数据与保留数据无关紧要。对于每个循环,您只需连接数据,然后在循环结束时打印它。结果是一样的。

–m0skit0
11年8月18日在12:02

它是否是循环进度的指示器,这很重要。

– gregseth
2011年8月18日在14:50

您从未在问题中说过或在问题中的任何地方都要求这样做。

–m0skit0
2012年11月20日16:17

#16 楼

如前所述,Pedro曾说,没有换行且有空格的回声有效(提供“ 9”是真实的[BackSpace])。
<nul set /p=.9    Hello everyone

我有在新控制台上使其无法在Windows 10中工作时出现了一些问题,但是通过以下方式进行了管理。
在CMD类型中:
echo .◘>bs.txt

我通过按[Alt] + [8]出现了“◘”
(实际符号可能会因代码页而异)。
然后,可以使用Notepad.exe将“ bs.txt”的结果轻松复制到需要的地方。
@echo off
<nul set /p "_s=.◘    Hello everyone"
echo: here


#17 楼

使用Bill Stewart出色的“ Shell脚本工具包”中的EchoX.EXE。
如何在Windows Cmd脚本中禁止换行:
@Echo Off
Rem Print three Echos in one line of output
EchoX -n "Part 1 - "
EchoX -n "Part 2 - "
EchoX    "Part 3"
Rem

Part 1 - Part 2 - Part 3
{empty line}
d:\Prompt>

此用法的帮助是:
Usage: echox [-n] message
  -n       Do not skip to the next line.
  message  The text to be displayed.

该实用程序小于48K,应位于您的Path中。它可以做的更多事情:-在不移动到下一行的情况下打印文本-在一定宽度内以左,中或右对齐的文本打印-带有制表符,换行符和Return的打印文本-前景色和背景色打印文本
该工具包还包含十二种出色的脚本编写技巧。下载页面还包含其他三个有用的工具包。

#18 楼

此处的答案较晚,但是对于需要在一行中写特殊字符的任何人,他们发现dbenham的答案太长了约80行,并且在仅使用set /p的限制下其脚本可能会中断(也许由于用户输入),这是可能最简单的方法是将.bat或.cmd与已编译的C ++或C语言可执行文件配对,然后仅对coutprintf字符进行配对。如果您正在显示某种进度条或某些使用字符的东西(如OP一样),这也将使您可以轻松地多次写到一行。

评论


@jiggunjer你确定吗?从Win-7 cmd窗格中获得的printfing提示我“'printf'无法识别为内部或外部命令,可操作程序或批处理文件。”

–很少需要“莫妮卡在哪里”
16年9月2日在18:03

printf不是Windows固有的。这是一个Windows问题。

–kayleeFrye_onDeck
16-9-29在17:57

@kayleeFrye_onDeck我想你的评论是针对jiggunjer的,而不是我;我的问题是建议在格式化很重要的情况下,将C和C ++用作Shell命令的完全独立于平台的替代方法。

–很少需要“莫妮卡在哪里”
16-9-29在22:34



父亲,请原谅我,因为我已经略读了。

–kayleeFrye_onDeck
16-09-30在0:24

但是,然后需要正确解析外壳程序的输入。例如,这样的程序将如何打印引号?

– Alex
17 Mar 20 '17在22:06