SET / p未在Batch中集中。空白问题

时间:2012-08-06 14:54:30

标签: batch-file batch-processing

这是我的TXT:

echo         x  1.   Enter               x  
echo         x  2.   Leave               x
echo         xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo:

set /p Menu=               Enter number {1,2}: 

if not '%Menu%'=='' set Menu=%Menu:~0,1%
if '%Menu%'=='1' goto ConvM

我的txt在家中转换为* .bat,当批处理运行时,短语“输入数字{1,2}:”的中心部分正好位于分隔符“x”的中间。结果如下图所示:

     x  1.   Enter               x  
     x  2.   Leave               x
     xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

          Enter number {1,2}:

我的txt在我工作的公司转换为* .bat,当批处理运行时,它会显示偏移量,如下所示:

     x  1.   Enter               x  
     x  2.   Leave               x
     xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Enter number {1,2}:


我将我的txt也转换为CMD但结果是一样的。在家里我有一个Windows XP,在工作中我有Windows 7.

如何在任何计算机中将“输入数字{1,2}:”与“x”集中在一起?

1 个答案:

答案 0 :(得分:4)

不幸的是,Windows 7(我认为Vista也是如此)忽略了SET /P提示符中的前导空格。空白字符包括空格,制表符和不间断空格(0xFF)。

解决方案不直观,但很简单。只需在提示符前加一个退格(0x08)字符。下面的代码以编程方式定义包含退格符的变量。根据需要,可以很容易地将其包含在任何提示中。

@echo off
setlocal

::Define a BS variable containing a backspace (0x08) character
for /f %%A in ('"prompt $H & echo on & for %%B in (1) do rem"') do set "BS=%%A"

echo         x  1.   Enter               x
echo         x  2.   Leave               x
echo         xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo:

set /p Menu=%BS%               Enter number {1,2}:

通常退格会导致行光标向上移动一个位置,然后下一个字符将覆盖那里的内容。但由于提示总是从第一个位置开始,因此没有空间来备份。退格有效地不接受允许在提示中引出空格: - )

如果需要,您可以在退格区前放置另一个角色,但不需要。退格键将行光标向后移动一个位置,然后您所需的提示将覆盖不需要的字符。

set /p Menu=x%BS%               Enter number {1,2}:

编辑 - 以下是定义BS变量的FOR /F行的解释

当ECHO为ON时,PROMPT命令控制显示为每行输出前缀的文本。默认情况下,它是当前目录,后跟>字符。

使用PROMPT $H会导致提示为<backspace><space><backspace>。因此,REM之类的命令会导致输出<backspace><space><backspace>REM

在一行上有一串命令被执行。通常,如果命令出现在发出ECHO ON的同一行上,则不会回显命令。该规则的例外是作为FOR DO子句的一部分出现的任何命令 回显。这就是REM命令在FOR循环中“执行”的原因 - 所以我们得到了REM命令的输出。

整个命令串在外部FOR /F循环内执行。该字符串用单引号括起来告诉FOR /F执行命令。在单引号内,字符串用双引号括起来。双引号保护命令连接&运算符。通常,一串命令不能用双引号括起来。但是由于FOR /F的工作原理,它适用于这种情况。命令通过CMD /C "command string"隐式执行。因此,在这种情况下使用双引号是完全可以接受的。

如果未使用双引号,则必须使用&转义^个字符:

('prompt $H ^& echo on ^& for %%B in (1) do rem')

最后,由于默认FOR /F DELIMS<tab><space>,因此REM命令的输出将被解析为令牌,并且仅保留第一个令牌。最终结果是BS值由单个<backspace>字符组成。