繁体   English   中英

相当于“echo -n”的Windows不再适用于Win7

[英]Windows equivalent of “echo -n” no longer works in Win7

我在Windows cmd.exe (至少高达XP)中有一个漂亮的技巧来模拟UNIX echo的行为而没有换行符echo -n 例如,命令:

<nul: set /p junk= xyzzy

将导致正好六个字符输出,前导空格和字符串“xyzzy”,没有别的。

如果你有兴趣,为什么这个作品,它实际上是一个输入指令,输出" xyzzy"作为提示,然后分配该输入前等待用户输入junk环境变量。 在这种特殊情况下,它不等待用户输入,因为它抓取来自nul设备的输入。

在(例如)处理循环中的文件(每个文件一次迭代)时,它在cmd脚本中非常有用,您希望每行列出多个文件。 通过使用这个技巧,您可以简单地输出每个文件名后跟一个空格而不是换行符,然后在循环之后输出换行符来完成:

Processing files:
    file1.txt file42.txt p0rn.zip

现在我发现,在Windows 7下,空格不再输出,所以我得到的是:

Processing files:
file1.txtfile42.txtp0rn.zip

有没有办法我可以set /p再次开始尊重我的空间,或者在Win7中有另一种方式来达到同样的效果吗?

我试过引用,使用. (在echo )甚至用^转义字符串,但它们似乎都不起作用:

C:\Pax> <nul: set /p junk= xyzzy
xyzzy

C:\Pax> <nul: set /p junk=" xyzzy"
xyzzy

C:\Pax> <nul: set /p junk=' xyzzy'
' xyzzy'

C:\Pax> <nul: set /p junk=. xyzzy
. xyzzy

C:\Pax> <nul: set /p junk=^ xyzzy
xyzzy

我需要的是:

C:\Pax> some_magical_command_with_an_argument xyzzy
 xyzzy

这将让我在开始的空间(S) 结尾没有换行符。

这与paxdiablo的答案非常相似,除了我使用混合JScript /批处理文件而不是临时VBScript文件。

我的脚本名为jEval.bat - 它只是评估任何有效的JScript表达式,并将结果写入stdout,可选择使用尾随换行符。 这个愚蠢的小脚本对于批量编程非常有用。

假设jEval.bat位于当前文件夹中,或者位于PATH中的某个位置,那么您可以执行以下操作:

call jeval "' xyzzy'"

这是脚本。 这真的很简单。 大多数代码都与文档,错误处理和内置帮助系统有关。

@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment

::************ Documentation ***********
:::
:::jEval  JScriptExpression  [/N]
:::jEval  /?
:::
:::  Evaluates a JScript expression and writes the result to stdout.
:::
:::  A newline (CR/LF) is not appended to the result unless the /N
:::  option is used.
:::
:::  The JScript expression should be enclosed in double quotes.
:::
:::  JScript string literals within the expression should be enclosed
:::  in single quotes.
:::
:::  Example:
:::
:::    call jEval "'5/4 = ' + 5/4"
:::
:::  Output:
:::
:::    5/4 = 1.25
:::

::************ Batch portion ***********
@echo off

if "%~1" equ "" (
  call :err "Insufficient arguments"
  exit /b
)
if "%~2" neq "" if /i "%~2" neq "/N" (
  call :err "Invalid option"
  exit /b
)
if "%~1" equ "/?" (
  setlocal enableDelayedExpansion
  for /f "delims=" %%A in ('findstr "^:::" "%~f0"') do (
    set "ln=%%A"
    echo(!ln:~3!
  )
  exit /b
)
cscript //E:JScript //nologo "%~f0" %*
exit /b

:err
>&2 echo ERROR: %~1. Use jeval /? to get help.
exit /b 1


************ JScript portion ***********/
if (WScript.Arguments.Named.Exists("n")) {
  WScript.StdOut.WriteLine(eval(WScript.Arguments.Unnamed(0)));
} else {
  WScript.StdOut.Write(eval(WScript.Arguments.Unnamed(0)));
}

这不是使用set或其他cmd -internal东西,但你可以使用cscript (也包含在标准的Windows安装中)来做类似的事情。 您甚至可以通过使用创建临时vbs文件从cmd文件本身控制它(没有要维护的单独文件)。

将此代码放在cmd文件中:

rem Create the VBS file to output spaces and a word.

echo.for i = 1 to WScript.Arguments.Item(0) >spacetext.vbs
echo.     WScript.StdOut.Write ^" ^" >>spacetext.vbs
echo.next >>spacetext.vbs
echo.WScript.StdOut.Write WScript.Arguments.Item(1) >>spacetext.vbs

rem Do this once per word you want output (eg, in a loop).

cscript /nologo spacetext.vbs 0 Hello,
cscript /nologo spacetext.vbs 1 my
cscript /nologo spacetext.vbs 1 name
cscript /nologo spacetext.vbs 1 is
cscript /nologo spacetext.vbs 4 Pax.

rem Do this at the end to add newline and kill temp file.

echo.
del spacetext.vbs

这是你所期望的输出:

Hello, my name is    Pax.

好的,现在有正确的答案:你不能在Win7中使用set /p获得前导<space> Windows版本之间存在差异:

Syntax                |  XP                                 |  Vista and Windows 7
----------------------+-------------------------------------+-------------------------------------
<nul set /p =!msg!    |- If 1st char is quote, then trims   |- Trims leading white space chars.   
       or             |  that quote, and if at least one    |- If 1st non white space char is     
<nul set /p "=!msg!"  |  additional quote, than trims last  |  quote, then that quote is treated  
                      |  quote and all remaining chars.     |  as white space and trimmed, and if
                      |- If 1st non trimmed char is =, then |  at least one additional quote, then
                      |  syntax error.                      |  trims last quote and all remaining
                      |                                     |  chars.
                      |                                     |- If 1st non trimmed char is =, then
                      |                                     |  syntax error.
----------------------+-------------------------------------+-------------------------------------
<nul set /p ="!msg!"  |- Trims leading control chars and    |- Trims leading white space chars.
       or             |  spaces.                            |- If 1st non trimmed char is =, then 
<nul set /p "="!msg!""|- If 1st non trimmed char is =, then |  syntax error.
                      |  syntax error.                      |
----------------------+-------------------------------------+-------------------------------------

On Vista and Windows 7, the trimmed leading white space chars are:
    9  0x09  Horizontal Tab
   10  0x0A  New Line
   11  0x0B  Vertical Tab
   12  0x0C  Form Feed
   13  0x0D  Carriage Return
   32  0x20  Space
  255  0xFF  Non-breaking Space

资源

有关获得纯批次领先空间的其他技术,请参见此处

你的意思是这样的?

@ECHO OFF
SETLOCAL
FOR /l %%i IN (1,1,4) DO <NUL SET /p var="item %%i "

结果:

项目1项目2项目3项目4

或者你一开始绝对坚持一个空间?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM