现在,我们来说以下区段分隔符集的设置—delims=xxx。
- delims= 后的所有字符都将被作为分隔符使用。例如 delims=hanye ,实际分隔时,不是以 hanye 去分隔,而是以 h a n y e 这5个字符分别去分隔。
- 默认为空格和制表符分隔符。也就是说,即使不设置 delims= ,依然会使用空格和制表符作为分隔符的。
- 如果不想使用任何字符作分隔符,可以设置 delims= 为空。
- 因为在 ParsingKeywords 中,英文引号是用来括 ParsingKeywords 的,所以英文引号是不能作为 delims= 分隔符的。
- 如果设置任意字符为区段分隔符,则空格和制表符不再做为分隔符使用。
我们看如下示例:
::示例30
@echo off&setlocal enabledelayedexpansion set hanye=4:3 5:4 6:5 7:6 8:3 9:7 for %%a in (%hanye%) do ( for /f "tokens=1,2 delims=:" %%i in ("%%a") do ( set /a gu=%%i*2+%%j*2 set /a xing=%%i*%%j echo 长:%%i 宽:%%j 周长:!gu! 面积:!xing! ) ) pause |
在这里, for %%a in (%hanye%) do ( 没有指定区段分隔符,所以以默认的空格为分隔符。 for /f "tokens=1,2 delims=:" %%i in ("%%a") do ( 则指定了英文分号作为分隔符。注意,此时空格和制表符不再是分隔符。
如果我们要解析某文件,不分隔区段,则如下示例31:
::示例31
@echo off for /f "tokens=1 delims=" %%i in (hanyeguxing.txt) do echo %%i pause |
这样,每一行中的所有字符都将被显示出来。当然,他也可以写成这样:for /f "delims=" %%i in (hanyeguxing.txt) do echo %%i 。因为不使用 tokens=1 ,for /f 依然会把值赋给第一个变量 %%i 的。
那么换个角度,我们不设置 delims= ,而是使用 tokens=* ,依然可以将每一行中的所有字符都将被显示出来,即写成: for /f "tokens=*" %%i in (hanyeguxing.txt) do echo %%i 。
好了,我们来看一下skip=n 。
- skip=n,指定在文件的开头跳过的行数。
- n 值不能为数字以外的字符。
- n 值必须为大于0的数字,即不能为0。
- 如果不想跳过行,则不设置 skip=n 即可。
这个用起来很简单。关于截取任意中间行部分,我们将在后面的内容中讲到,因为他和 skip=n 没有多大关系了。
::示例32
@echo off for /l %%i in (1 1 9) do ( for /l %%j in (1 1 5) do set /p=第%%i行第%%j列 <nul echo. )>>Hanyeguxing.txt for /f "skip=3 tokens=*" %%i in (Hanyeguxing.txt) do echo %%i del /q Hanyeguxing.txt pause |
这样,除了 usebackq 以外, ParsingKeywords 中的关键字就讲完了。
现在,我们从 (set) 的角度,来看一下 for /f 。一般情况, (set) 可以分成以下3类,即文件类,字符串类,命令类(不使用 usebackq 的情况下)。
- 如果 (set) 是文件,但不能有空格,即:
for /F ["ParsingKeywords"] {%% | %}variable in (filenameset) do command [CommandLineOptions]
::示例33—删除文件 Hanye.txt 中的重复行,并输出到 Hanye_.txt
@echo off for /f "delims=" %%l in (Hanye.txt) do if not defined %%l set %%l=Hanyeguxing & echo %%l>>Hanye_.txt |
- 如果 (set) 是字符串,则需要用英文引号将其引起来。即:
for /F ["ParsingKeywords"] {%% | %}variable in ("LiteralString") do command [CommandLineOptions]
::示例34
@echo off&setlocal enabledelayedexpansion for /l %%i in (9 -1 0) do set Hanye=%%i !Hanye! for /f "tokens=*" %%i in ("!Hanye:~0,-1!") do echo %%i pause |
-
如果 (set) 为命令,则需要用英文单引号将其括起来,即:
for /F ["ParsingKeywords"] {%% | %}variable in ('command') do command [CommandLineOptions]
::示例35-变量中这四个字,每字与其他组合,不限定位数,可存在单文字,且不重复,有多少种组合
@echo off&setlocal enabledelayedexpansion set han=寒 夜 孤 星 set n=1 for %%i in (%han%) do ( set /a i+=1 &echo %%i set ye!i!=%%i ) :hanye set /a n+=1 if not defined ye%n% goto :guxing for /f "tokens=1* delims==" %%i in ('set gu 2^>nul') do ( set /a x+=1 set gu!x!=%%j!ye%n%! ) set /a f=n-1 if not defined str!ye%n%! for /l %%i in (1,1,%f%) do ( set /a x+=1 set gu!x!=!ye%%i!!ye%n%! ) set /a str!ye%n%!+=1 goto :hanye :guxing for /f "tokens=1* delims==" %%i in ('set gu 2^>nul') do echo %%j set /a xing=(1^<^<%i%)-1 echo %xing%种组合方法 pause |
这个时候,我们发现一个问题,即文件名中不能有空格。那么要想有空格该怎么办?使用 usebackq 。在使用 usebackq 的情况下:
-
如果 (set) 是文件,可以有空格,则可以用英文引号引起来,当然,没有空格时,也可以不引。即:
for /F ["usebackqParsingKeywords"] {%% | %}variable in ("filenameset") do command [CommandLineOptions]
::示例36
@echo off for /l %%i in (1 1 9) do ( for /l %%j in (1 1 5) do set /p=第%%i行第%%j列 <nul echo. )>>"Hanye guxing.txt" for /f "usebackq tokens=*" %%i in ("Hanye guxing.txt") do echo %%i del /q "Hanye guxing.txt" pause |
-
如果 (set) 是字符串,则需要用英文单引号将其引起来。即:
for /F ["usebackqParsingKeywords"] {%% | %}variable in ('LiteralString') do command [CommandLineOptions]
::示例37-读注册表HKLM的Run下面的值
@echo off for /f "tokens=2 delims=:" %%i in ('reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run') do echo %systemDrive%%%i pause>nul |
-
如果 (set) 为命令,则需要用英文后引号将其括起来,即:
for /F ["usebackqParsingKeywords"] {%% | %}variable in (`command`) do command [CommandLineOptions]
::示例38-查看进程使用的端口
@echo off&setlocal enabledelayedexpansion echo 端口号 进程名称 &echo TCP协议: for /F "usebackq skip=4 tokens=2,5" %%i in (`netstat -ano -p TCP`) do ( call :Assoc %%i TCP %%j echo !TCP_Port! !TCP_Proc_Name!) echo UDP协议: for /F "usebackq skip=4 tokens=2,4" %%i in (`netstat -ano -p UDP`) do ( call :Assoc %%i UDP %%j echo !UDP_Port! !UDP_Proc_Name!) pause&goto :eof :Assoc for /F "tokens=2 delims=:" %%e in ("%1") do set %2_Port=%%e for /F "skip=2 usebackq delims=," %%a in (`"Tasklist /FI "PID eq %3" /FO CSV"`) do set %2_Proc_Name=%%~a |
|