用于解析 CSV 文件并输出文本文件的 Windows 批处理脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8520313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Windows batch script to parse CSV file and output a text file
提问by Jeff Webb
I've seen a response on another page (Help in writing a batch script to parse CSV file and output a text file) - brilliant code BTW:
我在另一个页面上看到了一个响应(帮助编写批处理脚本来解析 CSV 文件并输出一个文本文件) - 精彩的代码 BTW:
@ECHO OFF
IF "%~1"=="" GOTO :EOF
SET "filename=%~1"
SET fcount=0
SET linenum=0
FOR /F "usebackq tokens=1-10 delims=," %%a IN ("%filename%") DO ^
CALL :process "%%a" "%%b" "%%c" "%%d" "%%e" "%%f" "%%g" "%%h" "%%i" "%%j"
GOTO :EOF
:trim
SET "tmp=%~1"
:trimlead
IF NOT "%tmp:~0,1%"==" " GOTO :EOF
SET "tmp=%tmp:~1%"
GOTO trimlead
:process
SET /A linenum+=1
IF "%linenum%"=="1" GOTO picknames
SET ind=0
:display
IF "%fcount%"=="%ind%" (ECHO.&GOTO :EOF)
SET /A ind+=1
CALL :trim %1
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO !f%ind%!!tmp!
ENDLOCAL
SHIFT
GOTO display
:picknames
IF %1=="" GOTO :EOF
CALL :trim %1
SET /a fcount+=1
SET "f%fcount%=%tmp%"
SHIFT
GOTO picknames
It works brilliantly for an example csv file I made in the format:
它适用于我以以下格式制作的示例 csv 文件:
Header,Name,Place
one,two,three
four,five,six
However the actual file I want to change comprises of 64 fields - so I altered the tokens=1-10
to tokens=1-64
and increased the %%a
etc right up to 64 variables (the last being called %%BL
for example). Now, however, when I run the batch on my 'big' csv file (with the 64 tokens) nothing happens. No errors (good) but no output! (bad). If anyone can help that would be fantastic... am soooo close to getting the whole app working if I can just nail this last bit! Or if anyone has some example code that will do similar for an indefinite number of tokens... Ultimately I want to make a string which will be something like:
然而,我想要更改的实际文件包含 64 个字段 - 所以我更改了tokens=1-10
totokens=1-64
并将%%a
etc 增加到 64 个变量(%%BL
例如,最后一个被调用)。但是,现在,当我在“大”csv 文件(带有 64 个标记)上运行批处理时,什么也没有发生。没有错误(好)但没有输出!(坏的)。如果有人能提供帮助,那就太棒了……如果我能把这最后一点搞定,我就快要让整个应用程序正常工作了!或者,如果有人有一些示例代码,可以为无限数量的令牌做类似的事情......最终我想制作一个类似于以下内容的字符串:
field7,field12,field15,field18
回答by dbenham
Important update- I don't think Windows batch is a good option for your needs because a single FOR /F cannot parse more than 31 tokens. See the bottom of the Addendum below for an explanation.
重要更新- 我认为 Windows 批处理不是满足您需求的好选择,因为单个 FOR /F 无法解析超过 31 个标记。有关解释,请参阅下面附录的底部。
However, it is possible to do what you want with batch. This ugly code will give you access to all 64 tokens.
但是,可以使用批处理来做您想做的事情。这段丑陋的代码将使您可以访问所有 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
)
)
)
The addendum provides important info on how the above works.
附录提供了有关上述工作方式的重要信息。
If you only need a few of the tokens spread out amongst the 64 on the line, then the solution is marginally easier in that you might be able to avoid using crazy characters as FOR variables. But there is still careful bookkeeping to be done.
如果您只需要在线上 64 个中分布的几个标记,那么解决方案稍微容易一些,因为您可能能够避免使用疯狂的字符作为 FOR 变量。但是仍然需要仔细记账。
For example, the following will give you access to tokens 5, 27, 46 and 64
例如,以下内容将允许您访问令牌 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
)
)
)
April 2016 Update- Based on investigative work by DosTips users Aacini, penpen, and aGerman, I have developed a relatively easy method to simultaneously access thousands of tokens using FOR /F. The work is part of this DosTips thread. The actual code can be found in these 3 posts:
2016年4 月更新- 基于 DosTips 用户 Aacini、penpen 和 aGerman 的调查工作,我开发了一种相对简单的方法来使用 FOR /F 同时访问数千个令牌。这项工作是此 DosTips 线程的一部分。实际代码可以在这 3 个帖子中找到:
- Work with a fixed number of columns
- Work with varying numbers of columns
- Dynamically choose which tokens to expand within the DO clause
Original AnswerFOR variables are limited to a single character, so your %%BL strategy can't work. The variables are case sensitive. According to Microsoft you are limited to capturing 26 tokens within one FOR statement, but it is possible to get more if you use more than just alpha. Its a pain because you need an ASCII table to figure out which characters go where. FOR does not allow just any character however, and the maximum number of tokens that a single FOR /F can assign is 31 +1. Any attempt to parse and assign more than 31 will quietly fail, as you have discovered.
原始答案FOR 变量仅限于单个字符,因此您的 %%BL 策略不起作用。变量区分大小写。根据 Microsoft 的说法,您只能在一个 FOR 语句中捕获 26 个令牌,但如果您使用的不仅仅是 alpha,则可以获得更多令牌。它很痛苦,因为您需要一个 ASCII 表来确定哪些字符去哪里。但是 FOR 不允许任何字符,单个 FOR /F 可以分配的最大标记数是 31 +1。正如您所发现的那样,任何解析和分配超过 31 个的尝试都会悄悄地失败。
Thankfully, I don't think you need that many tokens. You simply specify which tokens you want with the TOKENS option.
值得庆幸的是,我认为您不需要那么多代币。您只需使用 TOKENS 选项指定您想要的令牌。
for /f "usebackq tokens=7,12,15,18 delims=," %%A in ("%filename%") do echo %%A,%%B,%%C,%%D
will give you your 7th, 12th, 15th and 18th tokens.
会给你你的第 7 个、第 12 个、第 15 个和第 18 个代币。
Addendum
附录
April 2016 UpdateA couple weeks ago I learned that the following rules (written 6 years ago) are code page dependent. The data below has been verified forcode pages 437 and 850.More importantly, the FOR variable sequence of extended ASCII characters 128-254 does not match the byte code value, and varies tremendously by code page. It turns out the FOR /F variable mapping is based on the underlying UTF-(16?) code point. So the extended ASCII characters are of limited use when used with FOR /F. See the thread at http://www.dostips.com/forum/viewtopic.php?f=3&t=7703for more information.
2016 年 4 月更新几周前,我了解到以下规则(6 年前编写)依赖于代码页。以下数据已针对代码页437和850进行了验证。更重要的是,扩展ASCII字符128-254的FOR变量序列与字节代码值不匹配,并且因代码页而异。事实证明 FOR /F 变量映射基于底层 UTF-(16?) 代码点。因此,当与 FOR /F 一起使用时,扩展 ASCII 字符的用途有限。有关更多信息,请参阅http://www.dostips.com/forum/viewtopic.php?f=3&t=7703 上的线程。
I performed some tests, and can report the following (updated in response to jeb's comment):
我进行了一些测试,可以报告以下内容(根据 jeb 的评论更新):
Most characters can be used as a FOR variable, including extended ASCII 128-254. But some characters cannot be used to define a variable in the first part of a FOR statement, but can be used in the DO clause. A few can't be used for either. Some have no restrictions, but require special syntax.
大多数字符都可以用作 FOR 变量,包括扩展的 ASCII 128-254。但是有些字符不能用于在 FOR 语句的第一部分中定义变量,但可以在 DO 子句中使用。有几个也不能用。有些没有限制,但需要特殊的语法。
The following is a summary of characters that have restrictions or require special syntax. Note that text within angle brackets like <space>
represents a single character.
以下是具有限制或需要特殊语法的字符的摘要。请注意,尖括号中的文本 like<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
Special characters like ^
<
>
|
&
must be either escaped or quoted. For example, the following works:
^
<
>
|
&
必须转义或引用等特殊字符。例如,以下工作:
for /f %%^< in ("OK") do echo "%%<" %%^<
Some characters cannot be used to define a FOR variable. For example, the following gives a syntax error:
某些字符不能用于定义 FOR 变量。例如,下面给出了一个语法错误:
for /f %%^= in ("No can do") do echo anything
But %%=
can be implicitly defined by using the TOKENS option, and the value accessed in the DO clause like so:
但是%%=
可以使用 TOKENS 选项隐式定义,并且在 DO 子句中访问的值如下所示:
for /f "tokens=1-3" %%^< in ("A B C") do echo %%^< %%^= %%^>
The %
is odd - You can define a FOR variable using %%%%
. But The value cannot be accessed unless you use the ~
modifier. This means enclosing quotes cannot be preserved.
该%
是奇数-您可以通过定义一个FOR变量%%%%
。但是除非您使用~
修饰符,否则无法访问该值。这意味着不能保留封闭引号。
for /f "usebackq tokens=1,2" %%%% in ('"A"') do echo %%%% %%~%%
The above yields %% A
以上产量 %% A
The ~
is a potentially dangerous FOR variable. If you attempt to access the variable using %%~
at the end of a line, you can get unpredictable results, and may even crash CMD.EXE! The only reliable way to access it without restrictions is to use %%~~
, which of course strips any enclosing quotes.
这~
是一个潜在危险的 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) character is special because <SUB>
literals embedded within batch scripts are read as linefeeds (<LF>
). In order to use <SUB>
as a FOR variable, the value must be somehow stored within an environment variable, and then %%%VAR%
will work for both definition and access.
在<SUB>
因为(0x1A的)字符是特殊的<SUB>
嵌入批处理脚本中的文字被解读为换行符(<LF>
)。为了<SUB>
用作 FOR 变量,该值必须以某种方式存储在环境变量中,然后%%%VAR%
才能用于定义和访问。
As already stated, a single FOR /F can parse and assign a maximum of 31 tokens. For example:
如前所述,单个 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 _=%%_
The above yields A=1 _=31
Note - tokens 2-30 work just fine, I just wanted a small example
以上产生A=1 _=31
注意 - 令牌 2-30 工作得很好,我只是想要一个小例子
Any attempt to parse and assign more than 31 tokens will silently fail without setting ERRORLEVEL.
任何解析和分配超过 31 个令牌的尝试都将在不设置 ERRORLEVEL 的情况下静默失败。
@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
You can parse and assign up to 31 tokens and assign the remainder to another token as follows:
您最多可以解析和分配 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 ^^=%%^^ _=%%_
The above yields @=1 ^=31 _=32 33 34 35
以上产量 @=1 ^=31 _=32 33 34 35
And now for the really bad news.A single FOR /F can never parse more than 31 tokens, as I learned when I looked at Number of tokens limit in a FOR command in a Windows batch script
现在是非常坏的消息。正如我在查看Windows 批处理脚本中 FOR 命令中的令牌数限制时了解到的那样,单个 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,32" %%A in ("!str!") do echo A=%%A B=%%B C=%%C
The very unfortunate output is A=1 B=31 C=%C
非常不幸的输出是 A=1 B=31 C=%C
回答by Aacini
My answer is comprised of two parts. The first one is a new answer I posted in help-in-writing-a-batch-script-to-parse-csv-file-and-output-a-text-file question that have not any limit in the number of fields.
我的回答由两部分组成。第一个是我在 help-in-writing-a-batch-script-to-parse-csv-file-and-output-a-text-file 问题中发布的新答案,该问题对字段数量没有任何限制.
The second part is a modification to that answer that allows to select which fields will be extracted from the csv file by additional parameters placed after the file name. The modified code is in UPPERCASE LETTERS.
第二部分是对该答案的修改,允许通过放置在文件名之后的附加参数选择将从 csv 文件中提取哪些字段。修改后的代码是大写字母。
@echo off
setlocal EnableDelayedExpansion
rem Create heading array:
set /P headingRow=< %1
set i=0
for %%h in (%headingRow%) do (
set /A i+=1
set heading[!i!]=%%~h
)
REM SAVE FILE NAME AND CREATE TARGET ELEMENTS ARRAY:
SET FILENAME=%1
IF "%2" == "" (FOR /L %%J IN (1,1,%i%) DO SET TARGET[%%J]=%%J) & GOTO CONTINUE
SET J=0
:NEXTTARGET
SHIFT
IF "%1" == "" GOTO CONTINUE
SET /A J+=1
SET TARGET[%J%]=%1
GOTO NEXTTARGET
:CONTINUE
rem Process the file:
call :ProcessFile < %FILENAME%
exit /B
:ProcessFile
set /P line=
:nextLine
set line=:EOF
set /P line=
if "!line!" == ":EOF" goto :EOF
set i=0
SET J=1
for %%e in (%line%) do (
set /A i+=1
FOR %%J IN (!J!) DO SET TARGET=!TARGET[%%J]!
IF !i! == !TARGET! (
for %%i in (!i!) do echo !heading[%%i]!%%~e
SET /A J+=1
)
)
goto nextLine
exit /B
For example:
例如:
EXTRACTCSVFIELDS THEFILE.CSV 7 12 15 18
EDITA simpler method
编辑一个更简单的方法
Below is a new version that is both simpler and easier to understand because it use a list of target elements instead of an array:
下面是一个更简单也更容易理解的新版本,因为它使用目标元素列表而不是数组:
@echo off
setlocal EnableDelayedExpansion
rem Create heading array:
set /P headingRow=< %1
set i=0
for %%h in (%headingRow%) do (
set /A i+=1
set heading[!i!]=%%~h
)
REM CREATE TARGET ELEMENTS LIST:
IF "%2" == "" (
SET TARGETLIST=
FOR /L %%J IN (1,1,%i%) DO SET TARGETLIST=!TARGETLIST! %%J
) ELSE (
SET TARGETLIST=%*
SET TARGETLIST=!TARGETLIST:* =!
)
rem Process the file:
call :ProcessFile < %1
exit /B
:ProcessFile
set /P line=
:nextLine
set line=:EOF
set /P line=
if "!line!" == ":EOF" goto :EOF
set i=0
for %%e in (%line%) do (
set /A i+=1
for %%i IN (!i!) DO (
IF "!TARGETLIST:%%i=!" NEQ "!TARGETLIST!" (
echo !heading[%%i]!%%~e
)
)
)
goto nextLine
exit /B
Also, this version does not require the desired fields be given in order.
此外,此版本不要求按顺序提供所需的字段。
EDIT
编辑
Oops! The for parameters stuff distracted my attention, so I was not aware of your last request:
哎呀!for 参数的东西分散了我的注意力,所以我不知道你的最后一个请求:
"Ultimately I want to make a string which will be something like:
field7,field12,field15,field18"
Just modify the last part of the program to do that:
只需修改程序的最后一部分即可:
:ProcessFile
set /P line=
:nextLine
set line=:EOF
set /P line=
if "!line!" == ":EOF" goto :EOF
set i=0
set resultString=
for %%e in (%line%) do (
set /A i+=1
for %%i IN (!i!) DO (
IF "!TARGETLIST:%%i=!" NEQ "!TARGETLIST!" (
set resultString=!resultString!%%~e,
)
)
)
set resultString=%resultString:~0,-1%
echo Process here the "%resultString%"
goto nextLine
exit /B
You may also remove the creation of the heading array, because you want NOT the headings! ;)
您也可以删除标题数组的创建,因为您不需要标题!;)
回答by Andy Smith
Using %%@ and %%` (not documented here) as start variables the max you can get is 71:
使用 %%@ 和 %%`(此处未记录)作为起始变量,您可以获得的最大值为 71:
@echo off
for /f "tokens=1-31* delims=," %%@ in ("%filename%") do (
echo:
echo 1=%%@
echo 2=%%A
echo 3=%%B
echo 4=%%C
echo 5=%%D
echo 6=%%E
echo 7=%%F
echo 8=%%G
echo 9=%%H
echo 10=%%I
echo 11=%%J
echo 12=%%K
echo 13=%%L
echo 14=%%M
echo 15=%%N
echo 16=%%O
echo 17=%%P
echo 18=%%Q
echo 19=%%R
echo 20=%%S
echo 21=%%T
echo 22=%%U
echo 23=%%V
echo 24=%%W
echo 25=%%X
echo 26=%%Y
echo 27=%%Z
echo 28=%%[
echo 29=%%\
echo 30=%%]
echo 31=%%^^
for /F "tokens=1-30* delims=," %%` in ("%%_") do (
echo 32=%%`
echo 33=%%a
echo 34=%%b
echo 35=%%c
echo 36=%%d
echo 37=%%e
echo 38=%%f
echo 39=%%g
echo 40=%%h
echo 41=%%i
echo 42=%%j
echo 43=%%k
echo 44=%%l
echo 45=%%m
echo 46=%%n
echo 47=%%o
echo 48=%%p
echo 49=%%q
echo 50=%%r
echo 51=%%s
echo 52=%%t
echo 53=%%u
echo 54=%%v
echo 55=%%w
echo 56=%%x
echo 57=%%y
echo 58=%%z
echo 59=%%{
echo 60=%%^|
echo 61=%%}
for /F "tokens=1-9* delims=," %%0 in ("%%~") do (
echo 62=%%0
echo 63=%%1
echo 64=%%2
echo 65=%%3
echo 66=%%4
echo 67=%%5
echo 68=%%6
echo 69=%%7
echo 70=%%8
echo 71=%%9
)
)
)
回答by Aacini
When I read this problem again and the solution proposed in the most-voted answer, I thought that a much simpler wayto make good use of a series of nested FOR /F commands could be developed. I started to write such a method, that would allowed to use 127 additionaltokens placing they in the ASCII 128-254 characters range. However, when my program was completed I discovered that the ASCII characters in the "natural" 128..254 order could not be used for this purpose...
当我再次阅读这个问题以及投票最多的答案中提出的解决方案时,我认为可以开发一种更简单的方法来充分利用一系列嵌套的 FOR /F 命令。我开始编写这样一个方法,它允许使用 127 个额外的标记,将它们放置在 ASCII 128-254 个字符范围内。但是,当我的程序完成时,我发现“自然”128..254 顺序中的 ASCII 字符不能用于此目的......
Then, a group of people were interested in this problem and they made a series of discoveries and developments that culminated in a method that allows to use many tokens(more than 43,000!) in a series of nested FOR /F commands. You may read a detailed description of the research and development involved in this discovery at this DosTips topic.
然后,一群人对这个问题感兴趣,他们进行了一系列的发现和开发,最终形成了一种允许在一系列嵌套的 FOR /F 命令中使用许多令牌(超过 43,000 个!)的方法。您可以在此 DosTips 主题中阅读有关此发现所涉及的研究和开发的详细说明。
Finally, I used the new method to modify my program, so it now allows the processing of up to 4094 simultaneous tokens (from a text file with long lines), but in a simple way. My application consists in a Batch file, called MakeForTokens.bat, that you may run with the number of desired tokens in the parameter. For example:
最后,我使用了新方法来修改我的程序,因此它现在允许处理多达 4094 个并发标记(来自具有长行的文本文件),但以一种简单的方式。我的应用程序包含一个名为MakeForTokens.bat的批处理文件,您可以使用参数中所需的令牌数量运行该文件。例如:
MakeForTokens.bat 64
The program generates a Batch file, called ForTokens.bat, that contain all the code necessary to manage such an amount of simultaneous tokens, including examples of how to process a file. In this way, the users just needs to insert their own file names and desired tokens in order to get a working program.
该程序生成一个名为ForTokens.bat的批处理文件,其中包含管理如此数量的同时令牌所需的所有代码,包括如何处理文件的示例。这样,用户只需要插入他们自己的文件名和所需的令牌即可获得一个工作程序。
In this particular case, this would be the final ForTokens.bat file that solve the problem as stated in this question, after most descriptive comments were deleted:
在这种特殊情况下,这将是解决此问题中所述问题的最终 ForTokens.bat 文件,删除大多数描述性注释后:
@echo off & setlocal EnableDelayedExpansion & set "$numTokens=65"
Rem/For Step 1: Define the series of auxiliary variables that will be used as FOR tokens.
call :DefineForTokens
Rem/For Step 2: Define an auxiliary variable that will contain the desired tokens when it is %expanded%.
call :ExpandTokensString "tokens=7,12,15,18"
Rem/For Step 3: Define the variable with the "delims" value that will be used in the nested FOR's.
set "delims=delims=,"
Rem/For Step 4: Create the macro that contain the nested FOR's.
call :CreateNestedFors
Rem/For Step 5: This is the main FOR /F command that process the file.
for /F "usebackq tokens=1-31* %delims%" %%%% in ("filename.txt") do %NestedFors% (
Rem/For Step 6: Process the tokens.
Rem/For To just show they, use the "tokens" variable defined above:
echo %tokens%
Rem/For You may also process individual tokens via another FOR /F command:
for /F "tokens=1-%tokens.len%" %%a in ("%tokens%") do (
echo Field #7: %%a
echo Field #12: %%b
echo Field #15: %%c
echo Field #18: %%d
)
)
goto :EOF
Support subroutines. You must not modify any code below this line.
:DefineForTokens
for /F "tokens=2 delims=:." %%p in ('chcp') do set /A "_cp=%%p, _pages=($numTokens/256+1)*2"
set "_hex= 0 1 2 3 4 5 6 7 8 9 A B C D E F"
call set "_pages=%%_hex:~0,%_pages%%%"
if %$numTokens% gtr 2048 echo Creating FOR tokens variables, please wait . . .
(
echo FF FE
for %%P in (%_pages%) do for %%A in (%_hex%) do for %%B in (%_hex%) do echo %%A%%B 3%%P 0D 00 0A 00
) > "%temp%\forTokens.hex.txt"
certutil.exe -decodehex -f "%temp%\forTokens.hex.txt" "%temp%\forTokens.utf-16le.bom.txt" >NUL
chcp 65001 >NUL
type "%temp%\forTokens.utf-16le.bom.txt" > "%temp%\forTokens.utf8.txt"
(for /L %%N in (0,1,%$numTokens%) do set /P "$%%N=") < "%temp%\forTokens.utf8.txt"
chcp %_cp% >NUL
del "%temp%\forTokens.*.txt"
for %%v in (_cp _hex _pages) do set "%%v="
exit /B
:CreateNestedFors
setlocal EnableDelayedExpansion
set /A "numTokens=$numTokens-1, mod=numTokens%%31, i=numTokens/31, lim=31"
if %mod% equ 0 set "mod=31"
set "NestedFors="
for /L %%i in (32,31,%numTokens%) do (
if !i! equ 1 set "lim=!mod!"
set "NestedFors=!NestedFors! for /F "tokens=1-!lim!* %delims%" %%!$%%i! in ("%%!$%%i!") do"
set /A "i-=1"
)
for /F "delims=" %%a in ("!NestedFors!") do endlocal & set "NestedFors=%%a"
exit /B
:ExpandTokensString variable=tokens definitions ...
setlocal EnableDelayedExpansion
set "var=" & set "tokens=" & set "len=0"
if "%~2" equ "" (set "params=%~1") else set "params=%*"
for %%a in (!params!) do (
if not defined var (
set "var=%%a"
) else for /F "tokens=1-3 delims=-+" %%i in ("%%a") do (
if "%%j" equ "" (
if %%i lss %$numTokens% set "tokens=!tokens! %%!$%%i!" & set /A len+=1
) else (
if "%%k" equ "" (set "k=1") else set "k=%%k"
if %%i leq %%j (
for /L %%n in (%%i,!k!,%%j) do if %%n lss %$numTokens% set "tokens=!tokens! %%!$%%n!" & set /A len+=1
) else (
for /L %%n in (%%i,-!k!,%%j) do if %%n lss %$numTokens% set "tokens=!tokens! %%!$%%n!" & set /A len+=1
)
)
)
)
endlocal & set "%var%=%tokens%" & set "%var%.len=%len%"
exit /B
You may download the MakeForTokens.bat application from this site.
您可以从该站点下载 MakeForTokens.bat 应用程序。