4

这是我的 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”上?

4

1 回答 1

4

SET /P不幸的是,Windows 7(我认为 Vista 也是)忽略了提示符中的前导空格。空白字符包括空格、制表符和不间断空格 (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}:

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

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

使用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 命令的输出将被解析为令牌,并且只保留第一个令牌。最终结果是由单个<backspace>字符组成的 BS 值。

于 2012-08-06T15:57:13.290 回答