重要更新- 我认为 Windows 批处理不是满足您需求的好选择,因为单个 FOR /F 无法解析超过 31 个标记。请参阅下面附录底部的解释。
但是,可以通过批处理执行您想要的操作。这个丑陋的代码将使您能够访问所有 64 个令牌。
for /f "usebackq tokens=1-29* delims=," %%A in ("%filename%") do (
for /f "tokens=1-26* delims=," %%a in ("%%^") do (
for /f "tokens=1-9 delims=," %%1 in ("%%{") do (
rem Tokens 1-26 are in variables %%A - %%Z
rem Token 27 is in %%[
rem Token 28 is in %%\
rem Token 29 is in %%]
rem Tokens 30-55 are in %%a - %%z
rem Tokens 56-64 are in %%1 - %%9
)
)
)
附录提供了有关上述内容如何工作的重要信息。
如果您只需要在线上的 64 个标记中分布一些标记,那么解决方案会稍微容易一些,因为您可能能够避免使用疯狂的字符作为 FOR 变量。但仍然需要仔细记账。
例如,以下内容将允许您访问令牌 5、27、46 和 64
for /f "usebackq tokens=5,27,30* delims=," %%A in ("%filename%") do (
for /f "tokens=16,30* delims=," %%E in ("%%D") do (
for /f "tokens=4 delims=," %%H in ("%%G") do (
rem Token 5 is in %%A
rem Token 27 is in %%B
rem Token 46 is in %%E
rem Token 64 is in %%H
)
)
)
2016 年 4 月更新- 基于 DosTips 用户 Aacini、penpen 和 aGerman 的调查工作,我开发了一种相对简单的方法,可以使用 FOR /F 同时访问数千个令牌。该工作是一部分这个 DosTips 线程。实际代码可以在这 3 个帖子中找到:
- 使用固定数量的列
- 使用不同数量的列
- 动态选择在 DO 子句中扩展哪些标记
原答案FOR 变量仅限于单个字符,因此您的 %%BL 策略不起作用。变量区分大小写。根据 Microsoft 的说法,您只能在一个 FOR 语句中捕获 26 个令牌,但如果您使用的不仅仅是 alpha,则可能会获得更多。这很痛苦,因为您需要一个 ASCII 表来确定哪些字符去哪里。然而,FOR 不允许任意字符,单个 FOR /F 可以分配的最大标记数为 31 +1。正如您所发现的,任何解析和分配超过 31 个的尝试都会悄悄失败。
值得庆幸的是,我认为您不需要那么多代币。您只需使用 TOKENS 选项指定所需的令牌即可。
for /f "usebackq tokens=7,12,15,18 delims=," %%A in ("%filename%") do echo %%A,%%B,%%C,%%D
会给你第 7 个、第 12 个、第 15 个和第 18 个令牌。
Addendum
2016 年 4 月更新 几周前,我了解到以下规则(6 年前编写)与代码页相关。以下数据已经过验证 代码页 437 和 850。 更重要的是,扩展 ASCII 字符 128-254 的 FOR 变量序列与字节代码值不匹配,并且因代码页而异。事实证明,FOR /F 变量映射基于底层 UTF-(16?) 代码点。因此,当与 FOR /F 一起使用时,扩展 ASCII 字符的用途有限。请参阅线程了解更多信息。
我进行了一些测试,并可以报告以下内容(根据jeb的评论更新):
大多数字符都可以用作 FOR 变量,包括扩展 ASCII 128-254。但有些字符不能在 FOR 语句的第一部分中用来定义变量,但可以在 DO 子句中使用。有几个也不能用。有些没有限制,但需要特殊语法。
以下是具有限制或需要特殊语法的字符的摘要。请注意,尖括号内的文本如<space>
代表单个字符。
Dec Hex Character Define Access
0 0x00 <nul> No No
09 0x09 <tab> No %%^<tab> or "%%<tab>"
10 0x0A <LF> No %%^<CR><LF><CR><LF> or %%^<LF><LF>
11 0x0B <VT> No %%<VT>
12 0x0C <FF> No %%<FF>
13 0x0D <CR> No No
26 0x1A <SUB> %%%VAR% %%%VAR% (%VAR% must be defined as <SUB>)
32 0x20 <space> No %%^<space> or "%%<space>"
34 0x22 " %%^" %%" or %%^"
36 0x24 $ %%$ %%$ works, but %%~$ does not
37 0x25 % %%%% %%~%%
38 0x26 & %%^& %%^& or "%%&"
41 0x29 ) %%^) %%^) or "%%)"
44 0x2C , No %%^, or "%%,"
59 0x3B ; No %%^; or "%%;"
60 0x3C < %%^< %%^< or "%%<"
61 0x3D = No %%^= or "%%="
62 0x3E > %%^> %%^> or "%%>"
94 0x5E ^ %%^^ %%^^ or "%%^"
124 0x7C | %%^| %%^| or "%%|"
126 0x7E ~ %%~ %%~~ (%%~ may crash CMD.EXE if at end of line)
255 0xFF <NB space> No No
特殊字符如^
<
>
|
&
必须转义或引用。例如,以下作品:
for /f %%^< in ("OK") do echo "%%<" %%^<
某些字符不能用于定义 FOR 变量。例如,以下给出语法错误:
for /f %%^= in ("No can do") do echo anything
But %%=
可以使用 TOKENS 选项隐式定义,并且在 DO 子句中访问的值如下所示:
for /f "tokens=1-3" %%^< in ("A B C") do echo %%^< %%^= %%^>
The %
是奇数 - 您可以使用定义 FOR 变量%%%%
。但是除非您使用该值,否则无法访问该值~
修饰符。这意味着无法保留括起来的引号。
for /f "usebackq tokens=1,2" %%%% in ('"A"') do echo %%%% %%~%%
以上产量%% A
The ~
是一个潜在危险的 FOR 变量。如果您尝试使用访问变量%%~
在一行的末尾,您可能会得到不可预测的结果,甚至可能导致 CMD.EXE 崩溃!不受限制地访问它的唯一可靠方法是使用%%~~
,这当然会删除所有包含的引号。
for /f %%~ in ("A") do echo This can crash because its the end of line: %%~
for /f %%~ in ("A") do echo But this (%%~) should be safe
for /f %%~ in ("A") do echo This works even at end of line: %%~~
The <SUB>
(0x1A) 字符很特殊,因为<SUB>
批处理脚本中嵌入的文字被读取为换行符 (<LF>
)。为了使用<SUB>
作为 FOR 变量,该值必须以某种方式存储在环境变量中,然后%%%VAR%
将适用于定义和访问。
如前所述,单个 FOR /F 最多可以解析和分配 31 个标记。例如:
@echo off
setlocal enableDelayedExpansion
set "str="
for /l %%n in (1 1 35) do set "str=!str! %%n"
for /f "tokens=1-31" %%A in ("!str!") do echo A=%%A _=%%_
以上产量A=1 _=31
注意 - 标记 2-30 工作得很好,我只是想要一个小例子
如果不设置 ERRORLEVEL,任何解析和分配超过 31 个标记的尝试都会失败。
@echo off
setlocal enableDelayedExpansion
set "str="
for /l %%n in (1 1 35) do set "str=!str! %%n"
for /f "tokens=1-32" %%A in ("!str!") do echo this example fails entirely
您可以解析并分配最多 31 个令牌,并将剩余的令牌分配给另一个令牌,如下所示:
@echo off
setlocal enableDelayedExpansion
set "str="
for /l %%0 in (1 1 35) do set "str=!str! %%n"
for /f "tokens=1-31*" %%@ in ("!str!") do echo @=%%A ^^=%%^^ _=%%_
以上产量@=1 ^=31 _=32 33 34 35
现在是真正的坏消息。正如我在查看时了解到的那样,单个 FOR /F 永远无法解析超过 31 个标记Windows 批处理脚本中 FOR 命令中的令牌数量限制
@echo off
setlocal enableDelayedExpansion
set "str="
for /l %%n in (1 1 35) do set "str=!str! %%n"
for /f "tokens=1,31,32" %%A in ("!str!") do echo A=%%A B=%%B C=%%C
非常不幸的输出是A=1 B=31 C=%C