Board logo

标题: [原创] [批处理命令一日一教学](12)字符串查找:find [打印本页]

作者: namejm    时间: 2009-6-7 02:11     标题: [批处理命令一日一教学](12)字符串查找:find

[一日一教学]批处理系列帖子索引 http://www.bathome.net/thread-2576-1-1.html

标题:一日一教学系列12_字符串查找:find
首发地址:http://bbs.bathome.net/viewthread.php?tid=4830
首发日期:2009.6.7
更新日期:无

上一篇:移动文件(夹):move http://bbs.bathome.net/viewthread.php?tid=4820
下一篇:待续

  当我要查找字符串的时候,第一个想到的命令,并不是我在本文中要讲解的find,而是比它更强悍的命令findstr。

  我对findstr是如此的依赖,以至于当我向各位讲解find命令的时候,我还得老老实实地在cmd窗口中敲下 find /? 这条命令,然后重重地按下回车键。

  find /? 的执行结果很快,唰的一下,帮助信息全出来了,与findstr命令10多个开关比起来,find仅有5个开关,算得上小巫见大巫了。

  find命令的基本格式是这样的:find "要查找的字符串" 要查找的文件,在这里,"要查找的字符串"这个内容是必不可少的,引号也是必须的。例如:find "bathome" d:\test.txt,表示在D盘根目录下的文本文件test.txt中查找含有 bathome 这一字符串的所有行。

  find的结果将会有两种情况:

  1、当文件中包含要查找的字符串时,将返回这个字符串所在位置的整行内容,具体格式为:第一行是"---------- ×××" (×××表示被查找的文件名,不包括引号对),第二行开始才出现包含字符串的整行内容;
  2、当文件中没有出现要查找的字符串时,find的结果仅仅返回"---------- ×××" 这一行内容(×××表示被查找的文件名,不包括引号对)。

  在查找指定字符串的时候,有的场合需要区分大小写,有的场合则对大小写并不在意,如何实现这些需求呢?

  很简单,在find的时候,添加或取消/i开关就是了,具体用法为:find /i "Abc" test.txt 表示不区分大小写,文本内容中含有 Abc、abc、ABC之类的都算;find "Abc" test.txt则严格区分字符大小写,只能匹配Abc,而不能匹配abc、ABC之类的字符。

  有时候,我们的需求并不是为了查找到某个字符串,而是要检测哪些行不含有特定的字符串,这个时候,可以使用开关/v,用法为:find /v "Abc" test.txt,它表示查找那些不含字符串Abc的行(Abc要区分大小写),如果不区分abc的大小写,那么,应该写成 find /i /v "Abc" test.txt。

  有时候,我们的要求很简单,仅仅只是想统计包含某个字符串的行总共有多少,这个时候,应该使用开关/c,写成 find /c "abc" test.txt。

  如果要在每行的行首显示行号,怎么办?那就写成 find /n "abc" test.txt 吧,它会把test.txt的内容都显示出来,与原文不一样的是,在每行内容的行首,都加上了行号——注意,它仅仅是在显示的时候加上行号而已,并没有真正改写文件的内容。

  如果你看到这样的命令:find /i /v /n "Abc" test.txt,请一点要先沉住气,不要被众多的开关弄得眼花缭乱吓趴下了,仔细对照上面的解释,相信你很快就会理解它的功能:在test.txt文件中,查找不包含字符串Abc的所有行,并在行首标上这些行的行号,查找的时候,字符串Abc不区分大小写。

  要是使用这样的语句:find /c /n "abc" test.txt,会出现什么样的结果呢?答案是:开关/n会被忽略掉,最终结果不会显示带行号的行内容,只会显示匹配的总行数而已。

  echo abcdef|find "abc",见过这种写法吗?它的含义是:在字符串abcdef中,检测是否存在字符串abc,也就是说,find支持管道符号,把管道符号之前的语句的执行结果,作为指定字符串的查找对象,甚至,你可以使用这样的语句:find "abc" test.txt|find "xyz",它表示在test.txt中查找同时存在字符串abc和字符串xyz的行,只要你愿意,你可以继续用管道符号把这个find语句连接下去,我们把这个过程称为多重过滤。

  在前面,我们说过,在 find "要查找的字符串" 要查找的文件 这条命令语句中,引号是必须的,要是我们要查找的内容就是双引号本身,那又该怎么办?

  答案很简单:把双引号本身先用双引号转义,再放到双引号对中,写成 find """" test.txt 的格式,如果要查找两个连续的双引号,则应该写成 find """""" test.txt。

  如果你想查找两行之间的字符块,我劝你趁早放弃这个疯狂的想法,因为,find仅仅针对位于同一行上的字符串,不能查找跨行的字符块。

  与findstr命令相比,find的功能确实有限得多,仅仅因为不支持正则表达式这一点,就有不少人把它视为鸡肋,从而遭到无情的抛弃。

  然而,find并非一无是处,凭借自己的独门绝技,在与findstr的竞争中,它挣得了一席之地。

  这些独门绝技是什么呢?(感谢BatCoder的提醒和zqz0012005的补充)

  1、统计含指定字符串的总行数。find /c "abc" test.txt可以统计test.txt中含有字符串abc的总行数,而findstr则没有直接提供该功能,需要配合for语句才能实现;
  2、find可以读取Unicode格式的文本,而findstr则不行;
  3、find可以过滤某些特殊字符,而findstr则不行,比如,我们在使用fsutil fsinfo drives语句查询磁盘分区的时候,如果想让盘符分行显示而不是显示在同一行上的时候(这在用for语句提取盘符的时候很有用),find可以大显身手,而findstr只能干瞪眼了,具体语句为:
  1. fsutil fsinfo drives|find /v ""
复制代码
【补充】
统计文件行数:
  1. type a.txt | find /c /v ""
复制代码

作者: tireless    时间: 2009-6-7 04:04

find 的参数不可以合并(如 /in),挨在一起也不可以(如 /i/n)。

find 支持查找通配符文件。如 find "1" *.txt
作者: namejm    时间: 2009-6-7 08:41

  呀,果真如此,第一点受findstr的影响,不做测试就写出来了,罪过罪过;第二点受微软自带帮助信息的误导,同样做作测试——唉,微软也太不厚道了,翻译过来语句不通也就罢了,竟然把意思都翻译错。赶紧修正^_^。
作者: zqz0012005    时间: 2009-6-7 12:08

find '"' test.txt

XP上出现:FIND: 参数格式不正确

应该把一个引号变成一对:
find """" test.txt

作者: curious    时间: 2009-6-7 12:17     标题: 总结一下,原文太长,但要点只有六个

1、find /v "Abc" test.txt  它表示查找那些不含字符串Abc的行
2、find /c "abc" test.txt  统计包含“abc”字符串的行数
3、find /i "Abc" test.txt   表示不区分大小写查找abc的行
4、find /c /n "abc" test.txt 开关/n会被忽略掉,最终结果不会显示带行号的行内容,只会显示匹配的总行数而已。
5、find "abc" test.txt|find "xyz",它表示在test.txt中查找同时存在字符串abc和字符串xyz的行,只要你愿意,你可以继续用管道符号把这个find语句连接下去,我们把这个过程称为多重过滤。
6、find """" test.txt   把一对双引号放在双引号对中(共2对),要查找的内容是双引号本身

[ 本帖最后由 curious 于 2009-6-7 12:30 编辑 ]
作者: namejm    时间: 2009-6-7 16:34

  find命令没有findstr用得熟练,临时抱佛脚写了一篇,竟然出现了多处错误,惭愧惭愧。当然,也怪自己粗心大意,没有对全部用法做实际测试,想当然地得出了一些错误的结论,真是误人子弟啊。以后得更加谨慎,在得出结论之前,一定实地测试一番,哪怕是最简单的情形也不放过。
作者: BatCoder    时间: 2009-6-7 19:34

既然findstr比find更强大,我们为什么还要学find呢,只学findstr不就行了吗?
find跟findstr相比,难道一点自己的优势都没有?
作者: zqz0012005    时间: 2009-6-7 19:52     标题: 回复 7楼 的帖子

1、find可以识别unicode格式文本,findstr不行。
2、find可以过滤某些特殊字符,比如
  1. fsutil fsinfo drives|find /v ""
复制代码
3、find可以直接显示包含待查找字符的行数,而findstr只能在前面加行号。
4、find.exe比findstr.exe体积小^_^
5、应该有效率上的不同(未具体测试,感兴趣者可以试下)。
作者: zqz0012005    时间: 2009-6-7 20:43

如果要查找的双引号不是一个,而是两个、三个或更多,findstr就彻底歇菜了

jm又忘了转义字符\了。
作者: namejm    时间: 2009-6-7 20:45

  哈哈,总是丢三落四的,错误不断啊。
作者: keen    时间: 2009-6-8 20:23

例如:find "bathome" d:\test.txt,表示在D盘根目录下查找含有 bathome 这一字符串的所有行。

这一句,是笔误,还是什么,我没看明白
作者: namejm    时间: 2009-6-8 22:51

  应该是在test.txt中查找字符串,是我写漏了,已经在顶楼补上了,谢谢提醒。
作者: dali    时间: 2009-6-11 09:37

不错  写出来总是比检查比人的难
作者: wangxin016    时间: 2009-6-11 15:49

是不是咱们批处理只支持txt么?
作者: Batcher    时间: 2009-6-11 20:46     标题: 回复 14楼 的帖子

不是
作者: wwjpl    时间: 2009-6-12 10:08

原帖由 namejm 于 2009-6-7 16:34 发表
  find命令没有findstr用得熟练,临时抱佛脚写了一篇,竟然出现了多处错误,惭愧惭愧。当然,也怪自己粗心大意,没有对全部用法做实际测试,想当然地得出了一些错误的结论,真是误人子弟啊。以后得更加谨慎 ...

此言差矣,我就觉得你写的非常好,适合像我这种初级批学员学习,简单明了,一看就懂。
希望把【一日一教学】越办越好。
作者: wwjpl    时间: 2009-6-12 10:32

最近每次登陆“批处理之家”都能看到一些非常好的批教学内容,非常高兴。
同时感谢写这些帖子的高手们,感谢你们的无私奉献和辛勤的劳动。
作者: yettybetty    时间: 2009-9-23 12:31

原帖由 namejm 于 7-6-2009 08:41 发表
  呀,果真如此,第一点受findstr的影响,不做测试就写出来了,罪过罪过;第二点受微软自带帮助信息的误导,同样做作测试——唉,微软也太不厚道了,翻译过来语句不通也就罢了,竟然把意思都翻译错。赶紧修正^_^。

那课本内容现在已经修正过了?
作者: pumahxh    时间: 2009-10-15 00:08

希望能将开关字母的完整英文也出来,这样比较容易记,辛苦了。
作者: keen    时间: 2009-10-15 14:27     标题: 回复 19楼 的帖子

请参看这个帖子中的chm电子书:
http://bbs.bathome.net/thread-5814-1-1.html
作者: tangweichao    时间: 2009-10-18 14:02

学无止境啊,看来还得努力
作者: lianfayong    时间: 2009-11-10 20:14

通谷易懂,  好教材 ,  支持
作者: digicr    时间: 2009-11-18 03:07

太激动了 真的 我这几天在1W多个小文件中需要提取每个文件中的数据
想到各种编程读取二进制文件,呵呵 没想到楼主的find就帮我解决了
谢谢!
作者: w561    时间: 2009-12-20 21:24

find 就这几个参数很容易学上手。。。原本以为都是一大堆文字。都有点害怕了。经过这么一实践,,又学到了一个命令的方法而且参数还不多就这4个/V /C /N /i  ..。快点出FINDSTR//
作者: lovesunny    时间: 2009-12-20 22:52

快点出FINDSTR吧,等的花儿都谢了^0^
作者: yog    时间: 2010-8-6 19:03

怎么没有下文了呢,看的好过瘾。JM是不是有事,有没有人着手接着写下去。期待中。
作者: andy七少    时间: 2011-6-11 10:31

有的用法不经常用老忘,今天过来在看一遍,好东西看一遍是不够的
作者: welllib    时间: 2011-6-16 10:18

v reverse
c count
i 這個不知道
n row number
作者: xslxslxsl    时间: 2011-7-21 22:51

相当不错的啊,楼主太谦虚了啊!
作者: zaixinxiangnian    时间: 2011-8-14 20:51

find  /i   (查找的字符串不区分大小写)
       /V   (查找不包含某字符串的行)
     /C  (显示包含某字符串的行数)
     /N  (在包含某字符串的行头加上行号)
才四个啊,,,,,没有五个啊
作者: xslxslxsl    时间: 2011-8-17 23:22

find是很不错,谢谢楼主哦
作者: QIAOXINGXING    时间: 2011-9-29 17:20

适合我们初学的
作者: hankfernandez    时间: 2012-12-23 16:17

find 的参数不可以合并(如 /in),挨在一起也不可以(如 /i/n)。

find 支持查找通配符文件。如 find "1" * ...
tireless 发表于 2009-6-7 04:04



确实,早点看到就好了,我在电脑上又试了半天才发现。
作者: 林小七    时间: 2013-1-11 10:31

fsutil fsinfo drives|find /v /n ""  命令为你什么会换行呢??难道哦是\转义字符???为什么把第一行的回车也标记上了有fsutil fsinfo drives|find /v /n "",求解
作者: suseek    时间: 2013-9-8 18:47

i    ignore
作者: wrsbj    时间: 2015-1-2 15:28

多谢楼主,学习了很有用
作者: bakatu    时间: 2017-4-27 13:04

学习了,感谢
作者: dingcool    时间: 2017-4-28 08:48

非常酷~~~~~~~~~~




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2