windows bat系列4:for处理案例一 逐行处理&字段分割

xiaoxiao2021-02-28  38

背景

假设有文件内容如下,其以列表形式显示了不同文件夹中文件数量,要求提取清单列中最后一列的数字

CHECK IS THERE ANY INTERFACE FILES IN I/O DIRS ------------------------------------------------------------------------------- 08 JUN 18 16:40:24 FILES IN ..\BNK.DATA\OFSDATA\AIO.IN.DIR: 0 FILES IN AIO.IN.FILE: 0 FILES IN F.AIOCARD.CREDIT.OUT: 0 FILES IN ..\BNK.DATA\OFSDATA\RTGS.IN.DIR: 0 FILES IN RTGS.IN.FILE: 0 FILES IN RTGS.OUT.FILE: 0 FILES IN ..\BNK.DATA\OFSDATA\RTGS.OUT.DIR: 0 FILES IN OFS.IN: 0 FILES IN SWIFT.FTP\F.DE.I.MS000: 0 FILES IN SWIFT.FTP\F.DE.O.MS000: 93

代码

@echo off ::setlocal setlocal enabledelayedexpansion rem into current path cd %~dp0 set FILENAME=%~dp0chkio_out.txt for /f "delims=^" %%i in (%FILENAME%) do ( @echo %%i | findstr /B "FILES" >nul && (set str=%%i & (for /f "tokens=4 delims= " %%m in ("!str!") do ( echo %%m))) ) endlocal pause

测试结果:

程序思路:

类似于此类(文件处理、字段抽取)问题,dos中提供功能强大的for语句进行处理。因而,处理思路如下:

1.      需要找到带文件个数的行,它们以FILES IN 开头,另外需要排除非FILES IN 开头的行;

2.      在1的基础上,对于每行文本,若以空格作为分割符,数字都处于第四列,因而需要想办法提取第四列内容。

程序说明:

1.      setlocal enabledelayedexpansion

设置本地为延时扩展,其实也就是:延迟变量,全称延迟环境变量扩展。下面是dos官方解释(setlocal/?)

开始批处理文件中环境改动的本地化操作。在执行 SETLOCAL 之后所做的环境改动只限于批处理文件。要还原原先的设置,必须执行 ENDLOCAL。达到批处理文件结尾时,对于该批处理文件的每个尚未执行的 SETLOCAL 命令,都会有一个隐含的 ENDLOCAL 被执行。

2.      cd %~dp0

进入脚本所在目录,脚本和待处理的文件(chkio_out.txt)放在同一目录

3.      set FILENAME=%~dp0chkio_out.txt

拼接完整的待处理路径名;

4.      for /f "delims=^" %%iin (%FILENAME%) do (

@echo %%i | findstr /B"FILES" >nul && (set str=%%i & (for /f "tokens=4delims= " %%m in ("!str!") do (

             echo%%m)))

)

此双层for语句为文件处理主体,具体分析如下:

a.      外层for循环以^(换行符)作为分隔符,逐行读取文件内容;

b.      @echo %%i | findstr /B"FILES" >nul

首先echo每行内容,再采用管道过滤以FILES开头的行,findstr的参数/B表示:在一行的开始配对模式,之后将结果重定到nul(不打印到屏幕)

c.      set str=%%i & (for /f"tokens=4 delims= " %%m in ("!str!") do ( echo %%m)))

经过前一轮for处理,我们抽取出所有以FILES开头的行。此处再进行第二层处理,重新将每行内容赋予变量str(字符串),再对字符串进行字段分割:

tokens=4表示将分割产生的第四个字段传递到循环体;

delims= (注意等号后面有空格)表示以空格分割字符串

!str!      表示字符串内容,因为采用延时绑定,需要用!!取变量内容

echo %%m          最后echo出结果。

符号小结:

| 前面命令输出结果作为后面命令的输入内容 || 前面命令执行失败的时候才执行后面的命令 & 前面命令执行后接着执行后面的命令 && 前面命令执行成功了才执行后面的命令

总结:

这种文件处理/字段分割的例子,首先要对照文件安内容设计清晰的处理思路,DOS中FOR命令是处理此类问题的能手,读者只要自己写几个,就能孰能生巧。

附dos帮助手册:

FOR

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters] FOR /F ["options"] %variable IN ("string") DO command [command-parameters] FOR /F ["options"] %variable IN ('command') DO command [command-parameters] fileset 为一个或多个文件名。继续到 fileset 中的下一个文件之前, 每份文件都被打开、读取并经过处理。处理包括读取文件,将其分成一行行的文字, 然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用 For 循环。 以默认方式,/F 通过每个文件的每一行中分开的第一个空白符号。跳过空白行。 您可通过指定可选 "options" 参数替代默认解析操作。这个带引号的字符串包括一个 或多个指定不同解析选项的关键字。这些关键字为: eol=c - 指一个行注释字符的结尾(就一个) skip=n - 指在文件开始时忽略的行数。 delims=xxx - 指分隔符集。这个替换了空格和跳格键的 默认分隔符集。 tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代 的 for 本身。这会导致额外变量名称的分配。m-n 格式为一个范围。通过 nth 符号指定 mth。如果 符号字符串中的最后一个字符星号, 那么额外的变量将在最后一个符号解析之后 分配并接受行的保留文本。 usebackq - 指定新语法已在下类情况中使用: 在作为命令执行一个后引号的字符串并且一个单 引号字符为文字字符串命令并允许在 file-set 中使用双引号扩起文件名称。 findstr 在文件中寻找字符串。 FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file] [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]] strings [[drive:][path]filename[ ...]] /B 在一行的开始配对模式。 /E 在一行的结尾配对模式。 /L 按字使用搜索字符串。
转载请注明原文地址: https://www.6miu.com/read-2622804.html

最新回复(0)