虽然我不知道为什么for
命令的行为就像它一样,有一些简单的规则与for
行为。这里我们只讨论token
条款。delims
, eol
, skip
and usebackq
另一天
Step 1- 找到标记子句。该子句被解析,并且对于每个请求的范围(只有一个,开始-结束,*
) 判断是否有效。如果不是有效请求(不在1-31范围内或者不在范围内)则被丢弃*
)但如果这是一个有效的请求,则为请求的每个元素分配一个“变量”(可能是一个表)以稍后保存为此令牌检索的数据。同时,定义一个“集合”(可能是位图掩码),设置令牌编号x(用于识别令牌中的令牌的编号)tokens
子句)将被检索。可以多次请求相同的令牌,但在“set”(或位掩码,...)中,唯一的效果是再次标记将检索令牌 x。
现在“集合”包含有效的位置(1-31,*
) 所请求的令牌。
一旦解析器结束处理for
配置中,输入文件被读入内存,或者执行命令以将其所有输出检索到内存中,或者将文字字符串声明为输入缓冲区。
Step 2- 准备行解析。保存令牌数据的表被初始化为空白,并将指针设置为表中的第一个位置(第一个令牌)。如果该行未被丢弃skip
, eol
或者因为它是空的,标记生成器将扫描输入缓冲区中的标记,否则,搜索该行的末尾并重复步骤 2 以查找找到的新行。
Step 3- 解析输入缓冲区。直到到达行尾,对于在该行中找到的每个标记,如果其位置在范围内(1-31 或*
令牌),根据“集合”进行检查以确定它是否已被请求(如果该令牌编号在集合中或者如果*
令牌正在处理中)。如果已请求,其数据是否包含在“表”中?在表指针指示的位置,指针递增,分词器继续重复步骤 3,直到到达行尾。
Step 4- 已到达线路末端。如果已检索到任何令牌或者请求的唯一令牌是*
(test for /f "tokens=*" %a in (" ") do echo %a
),执行里面的代码do
clause.
Step 5- 如果执行for
尚未取消且尚未到达缓冲区末尾,还有更多行需要处理,返回步骤 2。
这组步骤重现了问题中所有观察到的行为,但并不能证明这是否是问题的方式for
命令已编码。
现在,让我们对照问题中的代码进行检查
:::this prints - 1:[i] 2:[] 3:[] 4:[] 5:[] 6:[] 7:[]
for /f "tokens=1,1,1,1,1,1,1" %%a in ("i ii iii iv v vi vii") do (
@echo 1:[%%a] 2:[%%b] 3:[%%c] 4:[%%d] 5:[%%e] 6:[%%f] 7:[%%g]
)
7 个请求的令牌,因此表中的 7 个位置将传递给do
代码,但与“set”匹配的唯一标记是数字 1
:::this prints - 1:[i] 2:[ii] 3:[iii] 4:[iv] 5:[] 6:[] 7:[%g]
for /f "tokens=2,3,1-4" %%a in ("i ii iii iv v vi vii") do (
@echo 1:[%%a] 2:[%%b] 3:[%%c] 4:[%%d] 5:[%%e] 6:[%%f] 7:[%%g]
)
6个请求的token,在token表中的6个位置,“set”只会匹配1,2,3,4
:::this prints - 1:[i] 2:[ii] 3:[iii] 4:[] 5:[] 6:[] 7:[%g]
for /f "tokens=1-3,1-3," %%a in ("i ii iii iv v vi vii") do (
@echo 1:[%%a] 2:[%%b] 3:[%%c] 4:[%%d] 5:[%%e] 6:[%%f] 7:[%%g]
)
6个请求的token,在token表中的6个位置,“set”只会匹配1,2,3
setlocal disableDelayedExpansion
for /f "tokens=1-31,1-31,1-31" %%! in (
"33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 "
) do (
echo 1:[%%!-!] 30:[%%?-?] 31:[%%@-@] 32:[%%A-A] 33:[%%B-B] 34:[%%C-C] 35:[%%D-D] 36:[%%E-E] 37:[%%F-F] 38:[%%G-G] 90:[%%{-{]
)
93 个请求的令牌,令牌表中分配的 93 个位置,“集合”仅匹配元素 1-31
edited问题中添加了更多案例
空令牌的最大数量为 250
@echo off
for /f "tokens=1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31,1-31" %% in (
"1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1") do (
echo 0x02-%%- 0x07-%%- 0xFE-%%ю- 0xFB-%%ы- 0xFA-%%ъ-
)
No, you can request as much tokens as you can. I tested with 1625 1-30
and an aditional 31 (to ensure the parser keeps working), and it is handled without problems. Probably the limit is the line lengh. You can request up to 50530 (aprox) tokens (repeating 1-31,... to reach the line limit), but you are limited to get valid data for the 31 first tokens and blank data for the rest of the elements in the storage table, having to retrieve elements using a single character in the for
replaceable parameter. Using %%^A
(0x01, Alt-001) as the for
replaceable parameter, you can request up to %%ÿ
(0xFF, Alt-255)