Findstr命令
findstr是Window系统自带的命令,用途是查找指定的一个或多个文件文件中包含(或通过参数 /V来控制不包含)某些特定字符串的行,并将该行完整的信息打印出来,或者打印查询字符串所在的文件名。
例如我们新建一个test.txt的文本文件。内容:
hello world
world hello
打开cmd窗口,执行语句:
findstr /n ".*" test.txt
打印:
1:hello world
2:world hello1
这里/n、.*、test.txt含义:
/n ——在匹配的每行前打印行数。即“1:”这两个字符串。
.* ——在findstr中使用正则表达式,用于匹配部分或者更多的文件(.*代表匹配所有内容)。注意,正则表达式需要使用双引号。
另外,在findstr中,接受的以下元字符用于实现更高级的匹配:
. 通配符 任何字符
* 重复: 以前字符或类别出现零或零以上次数
^ 行中的位置:行首
$ 行中的位置:行尾
[class] 字符类:集中的任何一个字符
[^class] 反向类:非集中的任何一个字符
[X-y] 范围:指定范围内的任何字符
X 转义:元字符 X 的文字用途
?字的位置:字首
xyz> 字的位置:字尾
例如,匹配以hello1字符串结尾的行信息:
findstr /n ".*hello1" test.txt
打印:
world hello1
test.txt —— 执行搜索的文件,同样也可以利用通配符实现多种方式:
*.txt 搜索所有txt文档
abc.* 搜索所有指定(abc)名称的文件
*.* 搜索所有文件
for循环命令
基本用法:
格式:FOR [参数] %%变量名 IN (相关文件或命令) DO 执行的命令
作用:对一个或一组文件,字符串或命令结果中的每一个对象执行特定命令,达到我们想要的结果。
注意:在批处理文件中使用 FOR命令时,指定变量请使用%%variable,而不要用%variable。变量名称是区分大小写的,所以 %i 不同于 %I.
关于:for命令可以带参数或不带参数,带参数时支持以下参数:/d /l /r /f
实例
咱们用一个实例来熟悉下for循环的用法。将ports-desc.txt中的端口号取出来存入另一个文件ports.txt文件中,代码:
ports-desc.txt内容如下:
1 传输控制协议端口服务多路开关选择器
2 compressnet 管理实用程序
3 压缩进程
5 远程作业登录
...
首先 新建一个bat文件test.bat(在cmd窗口直接输入名称运行),获取文件每行的信息,用到一个循环:
@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n ".*" basic_port.txt')
do (
echo %%j
)
)
pause
打印:
1:1 传输控制协议端口服务多路开关选择器
2:2 compressnet 管理实用程序
3:3 压缩进程
4:5 远程作业登录
...
因为使用了/n参数,所以每行首有序列号及冒号。这里详解下:
(‘findstr /n ".*" basic_port.txt’) 会返回多行信息类似数组,for循环遍历每行字符串
delims=: 代表将每行字符串利用=后的字符进行分割
tokens=1* 1表示取每行分割后的第一列(可以理解为数组第一个arr[0])并存入变量%%i,后面所有的元素存入$$j()
以第一行为例,%%i等于1;$$j等于“1 传输控制协议端口服务多路开关选择器”
其次,遍历每行字符串,因此需要用到第二个循环,并且嵌套在其中:
第二个循环命令中,需要使用第一个循环%%j(即每行字符串)的值,必须使用变量的方式。而一般变量表示为%变量%,这里比较特殊,需要用!变量!的方式。像这样:
%%k in ("!string!") do(code...)
现在代码为:
@echo off
for /f "tokens=1* delims=:" %%i in ('findstr /n ".*" basic_port.txt')
do (
set set string=%%j
for /f "tokens=1* delims= " %%k in ("!string!") do (
echo %%k
)
)
pause
打印:
!string!
!string!
!string!
!string!
!string!
...
运行后,结果不对。度娘后发现嵌套循环的问题:变量延迟。需要在第一行加上“setlocal enabledelayedexpansion”
加上后:
@echo off&setlocal enabledelayedexpansion
for /f "tokens=1* delims=:" %%i in ('findstr /n "^[0-9]* " basic_port.txt')
do (
set string=%%j
for /f "tokens=1* delims= " %%k in ("!string!") do (
echo %%k
)
)
pause
现在就可以把数据一条条存入目标文件ports.txt文件中:
最后代码:
@echo off&setlocal enabledelayedexpansion
for /f "tokens=1* delims=:" %%i in ('findstr /n "^[0-9]* " basic_port.txt')
do (
set string=%%j
for /f "tokens=1* delims= " %%k in ("!string!") do (
%%k>>ports.txt
)
)
pause
>> 表示将数据追加到文件中。首次会新建这个文件。
> 一个时表示直接覆盖