batch-file - 为什么在 IN 之后 FOR 会因延迟子字符串扩展而失败?

标签 batch-file for-loop cmd delayedvariableexpansion

当使用立即扩展时,子字符串扩展在 for 循环(即 in 之后带括号的部分)的集合内工作(写 %% I 而不是批处理文件中的 %I:

set "X=123"
for %I in (%X:~1,1%) do @echo %I

但是,应用延迟扩展时失败:

for %I in (!X:~1,1!) do @echo %I

我希望输出是:

2

但它是:

!X:~1
1!

为什么会这样,我该如何预防?

我知道我可以通过引用集合并使用 ~ 来解决这个问题,但这不是我想要的:

for %I in ("!X:~1,1!") do @echo %~I

下面的命令行也失败了:

for %I in (!X:*2=!) do @echo %I

意外的输出是:

!

此外,使用 /R/L/R 开关的 for 命令行也会因此类子命令而失败-字符串语法。

这肯定与 =cmd 的标记分隔符这一事实有关,就像 SPACE , TAB, ;

最佳答案

根据线程 How does the Windows Command Interpreter (CMD.EXE) parse scripts?还有numerous comments在这里,答案在于特殊的方式for循环被解析。

关键是以下摘录的this answer (特别是斜体):

Phase 2) Process special characters, tokenize, and build a cached command block:
[...]

  • Three commands get special handling - IF, FOR, and REM
    [...]
    • FOR is split in two after the DO. A syntax error in the FOR construction will result in a fatal syntax error.
    • The portion through DO is the actual FOR iteration command that flows all the way through phase 7
      • All FOR options are fully parsed in phase 2.
      • The IN parenthesized clause treats <LF> as <space>. After the IN clause is parsed, all tokens are concatenated together to form a single token.
      • Consecutive token delimiters collapse into a single space throughout the FOR command through DO.

由于在解析for 之后发生延迟展开以及描述的行为, token 分隔符,如 SPACETAB, , ; , =等转换为单个 SPACE,因此子字符串扩展表达式如 !X:~1,1!更改为 !X:~1 1! , 和子字符串替换表达式,如 !X:*2=!更改为 !X:*2 ! , 它们都是无效的语法。

因此,要解决此问题,您需要通过 ^ 转义标记分隔符喜欢:

for %I in (!X:~1^,1!) do @echo %I

和:

for %I in (!X:*2^=!) do @echo %I

(顺便说一句, if statements 有一个非常相似的问题。)

关于batch-file - 为什么在 IN 之后 FOR 会因延迟子字符串扩展而失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50380393/

相关文章:

windows - 如何在循环中获取局部变量的子字符串?

windows - 使用批处理文件将文件从本地文件夹复制到 "C:\Windows\System32\"

java - 在cmd中执行后退出bat文件

postgresql - 如何从 .bat 文件在 heroku 上的远程 postgres 数据库上运行代码

batch-file - Windows批处理复制长字符串到剪贴板报错 "The syntax of the command is incorrect"

c - 为什么循环顺序会影响二维数组迭代时的性能?

c - 使用函数来减少重复性

r - R中的for循环回归分析

python - 使用 pip 安装包返回错误

batch-file - 使用 .bat (CMD) 从 TXT 文件中删除选定的行