昨天说到Windows自身没有提供grep,find命令功能不够强大。其实Windows还提供了一个可以在文件中寻找字符串的强大命令——findStr,这个命令支持正则表达式。
在命令提示符窗口输入如下命令可以查看命令使用帮助。
findstr /?
由于是Windows内置的,因此在中文版Windows中帮助信息是中文,这要比昨天介绍的Borland grep要友好一些:
C:\>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 按字使用搜索字符串。
/R 将搜索字符串作为一般表达式使用。
/S 在当前目录和所有子目录中搜索匹配文件。
/I 指定搜索不分大小写。
/X 打印完全匹配的行。
/V 只打印不包含匹配的行。
/N 在匹配的每行前打印行数。
/M 如果文件含有匹配项,只打印其文件名。
/O 在每个匹配行前打印字符偏移量。
/P 忽略有不可打印字符的文件。
/OFF[LINE] 不跳过带有脱机属性集的文件。
/A:attr 指定有十六进位数字的颜色属性。请见 "color /?"
/F:file 从指定文件读文件列表 (/ 代表控制台)。
/C:string 使用指定字符串作为文字搜索字符串。
/G:file 从指定的文件获得搜索字符串。 (/ 代表控制台)。
/D:dir 查找以分号为分隔符的目录列表
strings 要查找的文字。
[drive:][path]filename
指定要查找的文件。
除非参数有 /C 前缀,请使用空格隔开搜索字符串。
例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或
"there"。'FINDSTR /C:"hello there" x.y' 文件 x.y 寻找
"hello there"。
一般表达式的快速参考:
. 通配符: 任何字符
* 重复: 以前字符或类出现零或零以上次数
^ 行位置: 行的开始
$ 行位置: 行的终点
[class] 字符类: 任何在字符集中的字符
[^class] 补字符类: 任何不在字符集中的字符
[x-y] 范围: 在指定范围内的任何字符
\x Escape: 元字符 x 的文字用法
\<xyz 字位置: 字的开始
xyz\> 字位置: 字的结束
有关 FINDSTR 常见表达法的详细情况,请见联机命令参考。
还是用昨天的例子。我们要在z盘的\masm32\include下的所有.inc文件中搜索RtlIpv6AddressToString函数的声明,可以使用以下命令:
findstr /s /i "RtlIpv6AddressToString" z:\masm32\include\*.inc
命令执行结果如下:
C:\>findstr /s /i "RtlIpv6AddressToString" z:\masm32\include\*.inc
z:\masm32\include\dnslib.inc:RtlIpv6AddressToStringA PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\dnslib.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringA>
z:\masm32\include\dnslib.inc:RtlIpv6AddressToStringW PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\dnslib.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringW>
z:\masm32\include\ntdll.inc:RtlIpv6AddressToStringA PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\ntdll.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringA>
z:\masm32\include\ntdll.inc:RtlIpv6AddressToStringExA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\ntdll.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExA>
z:\masm32\include\ntdll.inc:RtlIpv6AddressToStringExW PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\ntdll.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExW>
z:\masm32\include\ntdll.inc:RtlIpv6AddressToStringW PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\ntdll.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringW>
z:\masm32\include\ntoskrnl.inc:RtlIpv6AddressToStringA PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\ntoskrnl.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringA>
z:\masm32\include\ntoskrnl.inc:RtlIpv6AddressToStringExA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\ntoskrnl.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExA>
z:\masm32\include\ntoskrnl.inc:RtlIpv6AddressToStringExW PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\ntoskrnl.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExW>
z:\masm32\include\ntoskrnl.inc:RtlIpv6AddressToStringW PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\ntoskrnl.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringW>
z:\masm32\include\wdmsec.inc:RtlIpv6AddressToStringA PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\wdmsec.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringA>
z:\masm32\include\wdmsec.inc:RtlIpv6AddressToStringExA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\wdmsec.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExA>
z:\masm32\include\wdmsec.inc:RtlIpv6AddressToStringExW PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
z:\masm32\include\wdmsec.inc: RtlIpv6AddressToStringEx equ <RtlIpv6AddressToStringExW>
z:\masm32\include\wdmsec.inc:RtlIpv6AddressToStringW PROTO STDCALL :DWORD,:DWORD
z:\masm32\include\wdmsec.inc: RtlIpv6AddressToString equ <RtlIpv6AddressToStringW>
可以看到,
z:\masm32\include\dnslib.inc
z:\masm32\include\ntdll.inc
z:\masm32\include\ntoskrnl.inc
z:\masm32\include\wdmsec.inc
均包括了RtlIpv6AddressToString函数的声明。