【问题标题】:Is this a bug in windows batch?这是Windows批处理中的错误吗?
【发布时间】:2013-12-16 17:34:38
【问题描述】:

我发现了一个我似乎无法解释的批处理脚本的特殊问题。也许这只是因为我对批处理的工作原理不够了解,但这里有一个示例批处理文件(test.bat):

@echo off

FOR /F "tokens=1*" %%i in ("%*") DO (
    echo %%j
)

如果我这样称呼它:

test.bat ab a,b "a,b"

我得到这个作为我的输出:

a,b "a b"

为什么去掉第二个逗号?如果我像这样转义逗号:

test.bat ab a,b "a^,b"

我得到正确的输出:

a,b "a,b"

它几乎就像','被for循环视为分隔符,但是当我查看FOR /?时,唯一的默认分隔符是空格。逗号未列为分隔符。如果我特别声明 delim 是一个空格,我仍然会得到这种行为。如果我转义引号,我仍然会得到这种行为。无论如何,如果逗号是一个分隔符,第一个逗号也应该被去掉,对吧?奇怪的是,如果你尝试在 for 循环中使用“usebackq”,你会得到完全相反的结果。第一个逗号被去掉,第二个逗号被保留:

a b "a,b"

为什么我必须转义引号内的所有逗号才能使其正常工作?是否有一些我缺少的 whindows 规则,或者它只是 Windows 批处理脚本中的一个错误?

【问题讨论】:

  • 您的代码报错 C:\Temp>test.bat ab a,b "a,b" a,b "a b" 系统找不到文件ê♠。

标签: windows batch-file for-loop


【解决方案1】:
  1. 逗号是命令行中的分隔符Reading second argument in batch file if first argument has commas
  2. 当你调用 FOR /F "tokens=1*" %%i in ("%*") 时,当展开时,它变成了

    FOR /F "tokens=1*" %%i in ("ab a,b "a,b"") 现在您看到双引号打开和关闭 2 次。 希望这会有所帮助。

  3. 我的建议,如果您需要复杂的命令行参数解析使用
:loop
 rem you code here
 shift
goto :loop

与 %* 一起使用时有一些限制。

【讨论】:

  • 那么为什么要打印两个内引号呢?如果它真的认为这是"ab a,b "ab"" 中的两组引号,为什么4 个引号中只有2 个会得到回显?它仍然使用空格作为分隔符。请注意,ab 不会打印出来,而不是 ab a,b"a
  • 这就是我在答案中提到第 3 点的原因。它仍然有一些奇怪的东西。如果您想更深入地查找 - 您可以进行一些搜索。但是,如果您想让脚本正常工作 - 您需要一种解决方法。
  • 是的,我可以做一个解决方法,但我只是想知道是否有人知道为什么批处理会以这种方式运行。此问题与 %* 无关。我可以创建一个变量并使用它而不是 %*。因此,带有 %* 的 for 循环的限制不适用于此处。逗号不是 FOR 循环的默认分隔符。我在网上查过,但没有找到关于这个主题的任何内容。
  • 逗号、等号和其他一些字符在命令行中被视为空格,除非被引用。在 for /f 内部,它就像一个命令行,并且有一些额外的限制。
【解决方案2】:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "line=a b a,b "a,b""
SET line
ECHO [%*]
FOR /f "tokens=1*" %%i IN ("%*") DO (ECHO %%j)
FOR /f "tokens=1*" %%i IN ("%line%") DO (ECHO %%j)
FOR /f "tokens=1*" %%i IN ("!line!") DO (ECHO %%j)
FOR /f "tokens=1*" %%i IN ('echo %line%') DO (ECHO %%j)

GOTO :EOF

运行上面可能会指向一个解释。这都是历史问题——当替换时——首先是 %var%,其次是 %%x,然后是 !var!第三个。

【讨论】:

  • 我仍然不明白为什么要删除逗号。什么是删除它,为什么?我不明白替换顺序与逗号被丢弃有什么关系。显然!line! 的替换方式与%line% 不同,但为什么呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 2023-03-11
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多