Board logo

标题: [文本处理] [讨论]批处理findstr和变量赋值法查找文本的结果和效率差异 [打印本页]

作者: jackerloo2009    时间: 2009-6-26 16:51     标题: [讨论]批处理findstr和变量赋值法查找文本的结果和效率差异

今天突然想起了前些日子讨论过的问题,有A,B两个文本,文本内的都是邮件地址,其中A文本内71332个地址,B文本有122530个地址,以上两个数据是我实测得出的,当时提问者的要求是找出A文本中跟B中重复的地址,并删除,只留下不重复的地址,至于B是个参照,可要可不要
     对于这个问题印象很深刻,自己思考写了个代码,是逐一对比的,也就是需要进行71332*122530次对比,结果一算下了我一跳,大概是87.4亿次比较,效率极低,所以就这个问题在①群提出,当时很多人都参与了讨论研究,当晚未果,第二天是我在问batman问题的时候,因为当晚他未在,顺便提出这个问题的,man直接给了代码,man的代码用到了变量赋值将乘积的工作量变成了和的工作量,只需要进行71332+122530此对比,即20万次比较,相对于87.4亿比较的工作量,缩短的效率就可想而知了,呵呵,这是前话,暂且放下不提。
      原本已经解决的问题,为何我又搬出来了呢?因为本人新手,很多东西我总是自己去测试,有些教程相信作者是很辛苦分享的,但是看得多了发现很多还是有一定的误区的,因此为了让自己的基础扎的牢实,以后给别人分享的时候不至于误导新手,我总是对一些模糊的模棱两可的代码用自己的思路去测试,不懂就问群里的各位前辈,以确定准确的知识点,由此引出了对findstr和for中变量赋值的探讨,也正是今天要提到的主题
      相信大家都知道findstr命令本身带有的参数也可以实现比较两个文本去掉重复,能达到和for变量赋值一样的效果,因此觉得测试它们之间到底哪个效率高,以便以后遇到次类似问题,优先选用高效的方法,以下是我演示的过程:
      最初for变量赋值的代码是没有疑问的,当然在这要提一点就是for变量赋值处理并生成结果888.txt用了38分钟,只要明白原理相信大家都可以写出来,我会在以后做出解释,暂且来谈谈findstr这个命令:
     首先我用了个简单的例子1.txt
  1. 124
  2.                                       125
  3.                                       145
  4.                                       147
复制代码
2.txt
  1. 124
  2.                                       125
  3.                                       547
  4.                                       856
复制代码
我用的命令是findstr /v /g:2.txt 1.txt测试,这里解释一下参数/v 只打印不包含匹配的行; /g:file 从指定的文件获得搜索字符串,然后看以上两个文本结果是145,147,这个是将1中跟2重复的去掉只保留1跟2不重复的,跟那两个邮件文本的要求是同理的,然后我就测试那两个超大邮件文本,时间用了6分钟效率倒是蛮高的,可是得到的结果跟for变量赋值的结果比较却少得可怜,这是什么原因导致的呢?是findstr对大文本的机制问题?还是我对命令的不完全了解?带着这个疑问到群里咨询,恰巧随风也在,讨论一会未果,batman也冒出来了,一语惊醒梦中人,他指出了我用findstr的疑问,因为我没有指明是否完全匹配,少了这个参数/x,结果自然大大改观,并就我测试的问题举了个例子:
                           1.txt
  1. 124
  2.                                       125
  3.                                       145
  4.                                       147
  5.                                       1243
  6.                                       1241
复制代码
2.txt
  1. 124
  2.                                       125
  3.                                       547
  4.                                       856
复制代码
同样使用上面的命令findstr /v /g:2.txt 1.txt测试,结果我们发现得多的答案还是145,147,这是什么原因呢?明明1文本内还有1243,1241啊,它怎么不要了呢?问题就出在这儿,如果不指明参数/x,命令解释是打印完全匹配的行,它会默认只要有124字符的都认为是相同的,所以它会抛弃1243,1241,想要得到我们准确的结果的话你可以测试加上参数/x
                代码如下
  1. findstr /v /x /g:2.txt 1.txt
复制代码
看到这个代码可能你会有疑问参数 /v 是只打印不包含匹配的行;/x 打印完全匹配的行,它们的并存不矛盾吗?呵呵,跟我一样以前以为这俩是矛盾的,为什么可以同时存在?man很明了的给了解释:只打印不包含完全匹配的行。如果不明白再仔细回味一下这句话,还是不明了,这个嘛只能建议start/call :新华字典 ^v^!
    都解决了,这回测试没问题了吧?走,再跟着我继续研究,for变量赋值得到的文本结果仍然未动,因为上次findstr的模糊寻找致使它很严肃的抛弃了很多真理,我再次测试重新加上了man前辈解释的/x参数,这次findstr生成的文本是666.txt,根据记录前后时间差得出的时间是19分钟,比起for变量赋值来效率果然大大提高,只用了它一半的时间,可是大家再跟我查看文本属性
          for变量赋值的结果888.txt
  1. 大小  289KB (296,671 字节)
复制代码
findstr的结果666.txt
  1. 大小  289KB (296,852 字节)
复制代码
你能发现什么?看起来大小一样,但是本文主要注重字节,我们比较发现它们是有差异的,差了181字节,到底差在哪?看来我还要做麻烦的比较了,但上帝很垂怜,打开这两个文本第一行就迥然不同,它们的排序都是a-z排列的,我们来看下前两行:
          for变量赋值的结果888.txt
  1. adrienpuget@wanadoo.fr
  2.                                          benedictembatso@hotmail.com
复制代码
findstr的结果666.txt
  1. AABIS@WANADOO.FR
  2.                                          adrienpuget@wanadoo.fr
  3.                                          benedictembatso@hotmail.com
复制代码
看出什么区别没有?findstr的结果明显多出了[email=AABIS@WANADOO.FR]AABIS@WANADOO.FR[/email]这么一行,而for变量赋值的方法没有,难道这两个有一个出错了??于是想了个办法,复制了这个邮件地址,打开A.txt用ctrl+f打开搜索字符串,发现A文本里可以查询到,同样在B文本里查询也能查询到,带着这个疑问将结果发给man看,man让我又加了一个参数/i,这个参数是什么呢?就是指定搜索不区分大小写,默认findstr搜索是区分大小写的,而for变量赋值法是不区分大小写的,当然就大小写的问题严格来说findstr是精确的,因为for变量赋值无法区分出大小写来,想来这是一个缺陷
      接下来我们接着测试研究,你会问既然findstr比for变量赋值法精确,为什么要加/i这个参数把大小写忽略了呢?这里就是我想研究的问题,到底findstr和for变量赋值法哪个更精确,假如它们得到的结果一致,至少我们以后就可以用效率高的代码,如果不一致到底哪个出错了?以后肯定要忽略效率而采用准确的代码咯!下面看新增参数的代码
                   如下
  1. findstr /v /x /i /g:2.txt 1.txt
复制代码
例子       1.txt
  1. 124
  2.                                       125
  3.                                       145
  4.                                       147
  5.                                       abc
  6.                                       CBD
  7.                                       ABC
复制代码
2.txt
  1. 124
  2.                                       125
  3.                                       547
  4.                                       856
  5.                                       cbd
  6.                                       abc
复制代码
首先我们来看不加参数/i,它是区分大小写的,得到的结果是145,147,CBD,ABC
我们看加上参数/i的结果是什么呢? 结果是145,147。这就是这个参数的作用,不区分大小写之后,它会认为CBD,ABC跟小写字母的是一致的,所以一同排除了,也就是我们看到的只有两个结果
     前面其实我们主要阐述了findstr寻找文本一些关键参数的作用和例子,那么在前面代码熟练了以后,我们下面开始简单介绍一下for变量赋值的代码,限于本人的理解水平,还望各位前辈指点
          先看个通俗的例子for /f "delims=" %%a in (a.txt) do echo %%a
如何理解它的通俗机制,我在这举个例子:我们去市场买苹果,老农把苹果都装在箱子里,摆在小摊上,我用这个例子来解释这个机制的动作,首先我们要从箱子a.txt中选苹果%%a,我们拿起一个苹果就是for这个动作,转了一圈看了一遍发现是好的就是"delims=" echo %%a,然后我们把苹果%%a放到手提袋里贮存起来,假设我们要买这一箱子a.txt苹果%%a,那我们都要看一遍echo %%a,也许解释的不够合理只是尽量通俗,好理解一些,下面看for变量赋值的代码
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt) do (
  4.           if not defined %%a set "%%a=i"
  5. )
  6.     for /f "delims=" %%a in (A.txt) do (
  7.           if not defined %%a echo %%a>>888.txt
  8. )
  9. echo %tm% %time%
  10. pause
复制代码
这里的代码除了包含我上面通俗解释的内容,还多了if not defined,它的意思我个人理解是:如果没有被赋值,这也是被列在if用法里的一个经典的代码,上面代码的意思是将B文本里的内容预读一遍,如果没有%%a没有被赋值,就将%%a赋值一遍,然后我们再从A文本里预读,预读的同时也判断这个%%a是否被赋值,当读到A里跟B文本中相同的内容时,它已经在B里被赋值了,所以会被第二句代码里的if not defined %%a过滤掉,剩下来的就满足了最初提问者的要求去掉A文本里跟B里重复的地址,得到的就是未重复的,呵呵,讲的或许不是很好理解,仍然用买苹果的例子来讲前面我们挑苹果是理想状态的,箱子里的苹果都是好的,就这个if not defined我举一个通俗例子,还是买苹果的问题老农有两个①②箱子,如同AB那两个文本,两个箱子里面都装了两样苹果,青香蕉和红香蕉,是老农不小心搞混了的,但是我来买苹果就喜欢①箱子里的,它个大好看,而且我只想要红香蕉,这时老农说,②箱子里的苹果青香蕉贴了个“青”字,红香蕉贴了个“红”字,我都扫描了一遍果真如此,他又说①箱子的也这样,这时我便开始扫描①箱子的,因为我只要红香蕉,在看②箱子的时候青香蕉贴“青”字的苹果就等于被赋值了,我以那个“青”字为参考,在挑①箱子的苹果时,看见贴“青”字的就丢掉,呵呵当然买东西的时候,是不敢这么干的,只是放在别处,这就是if not defined的效果。。
    现在我们对于findstr前面已经研究到位了,最佳跟for变量赋值比较的代码也已经定位了,根据findstr的代码
  1. (findstr /v /x /i /g:B.txt A.txt)>>555.txt
复制代码
按我们的分析,这个代码理论上应该已经等于for变量赋值的代码了,现在我们来做个结果比较
          for变量赋值的结果888.txt
  1. 大小  289KB (296,671 字节)
复制代码
findstr的结果555.txt
  1. 大小  289KB (296,629 字节)
复制代码
相信细心的你也能发现它们差了42字节,还差??我就不相信整不明白了。。。最后我只好用了findstr命令将最后的这两个文本结果做了比较,找出了它们的差异
              findstr /v /x /i /g:555.txt 888.txt 结果如下
  1. lccq@free.fr  这个地址555中没有 888有
  2.                             oriana=-du_7141@hotmail.com  这个地址555中没有 888有
  3.                             p*.tournois@chello.fr  这个地址555中有  888也有
  4.                             v-dupuit@caramail.com  这个地址555中没有 888有
  5.                            
复制代码
这样比较的是从888中去掉跟555重复的地址,得出结果如上
同样如果我反过来测试呢?
               findstr /v /x /i /g:888.txt 555.txt 结果如下
  1. korantin\ds@hotmail.fr 这个地址555中有 888中没有
  2.                            p*.tournois@chello.fr  这个地址555中有  888也有
  3.                            
复制代码
这样比较的是从555中去掉跟888重复的地址,得出结果如上
看到我标注的没有,唯独这出现了问题!

想请各位前辈对于最后的这部分给予指点,并就findstr和for变量赋值哪个的结果更准确也给予指点


邮件AB文本太大无法上传 http://d.namipan.com/sd/102572    A邮件文本的下载地址
                                         http://d.namipan.com/sd/102574    B邮件文本的下载地址

[ 本帖最后由 jackerloo2009 于 2010-5-23 19:57 编辑 ]
作者: 随风    时间: 2009-6-26 17:15

应该是行尾的空格在作怪。
作者: Batcher    时间: 2009-6-26 17:23

能否把附件上传到纳米盘、QQ中转站之类的网络磁盘上面,以便大家下载?
作者: Batcher    时间: 2009-6-26 17:34

这样来计算for命令花费的时间似乎有点不公平啊,呵呵。
可以参考这个帖子,提高一下for命令写文件的速度:http://bbs.bathome.net/thread-4831-1-1.html
作者: tireless    时间: 2009-6-26 18:47

应该加上 /L 参数吧?因为邮件地址中含有“.,而这个点在 findstr 中表示任何字符。例如:

str.txt 的内容是a.b
file.txt 的内容是a1b
执行 findstr /xg:str.txt file.txt,会把a1b找出来。

/L 参数的意思是,按字面搜索,也就是不使用正则表达式。
作者: jackerloo2009    时间: 2009-6-26 19:39     标题: 回复 4楼 的帖子

重新让随风优化过代码,重新挂机测试过
随风的代码比我的原代码多用了一分钟
作者: 随风    时间: 2009-6-26 19:56

优化后的代码为:
  1. @echo off
  2. set tm=%time%
  3. (for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a
  5. )>888.txt
  6. echo %tm% %time%
  7. pause
复制代码
比你之前的代码只是在变量名前面多加了个点,怎么会使效率如此低下?
节省了7万次开关I/O 居然会没有区别?
作者: zqz0012005    时间: 2009-6-26 20:16

5楼说的对,还应该加/L参数。

另外,findstr 本来就是不可信任的,存在诸多已知和未知的问题。在很多场合尽量不要用findstr。
  1. echo 王志慧|findstr ".*净"
  2. set>env.tmp
  3. findstr /l /v /x /g:env.tmp env.tmp
复制代码

作者: keen    时间: 2009-6-26 21:57     标题: 回复 7楼 的帖子

应该没有7万次的I/O开关。
楼主的代码只是把A中有,而B中没有的写入到888.txt中,从楼主得到的888.txt文件的大小(289k),把每个邮件地址算成13个字节左右(大概)。用289k除一下13字节,估计是2万多行。

不知道效率低了,是不是因为给变量加了个点作标示引起的,还是别的原因,有待研究。

有不对的地方,请指教。
作者: jackerloo2009    时间: 2009-6-27 09:39     标题: 回复 7楼 的帖子

09-06-27
今天早晨再次用7楼的代码进行测试,时间为39分04秒
仍旧比我的原代码多了1分钟,还请亲自验证,以及分析一下原因
作者: 随风    时间: 2009-6-27 09:45     标题: 回复 10楼 的帖子

不防给你原来的代码变量名也加上一个点,再测试,更公平
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a>>888.txt
  5. echo %tm% %time%
  6. pause
复制代码

作者: jackerloo2009    时间: 2009-6-27 11:04     标题: 回复 11楼 的帖子

额。。。这个测试了40分钟06秒
作者: 随风    时间: 2009-6-27 11:10

如果楼主有时间还可以再试试这段代码,看到底谁更快些。。
话说,7楼与11楼代码效率不相上下,实在有点想不通~
:
  1. @echo off
  2. set tm=%time%
  3. echo. >nul 3>888.txt
  4. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  5. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a
  6. echo. >nul 4>con
  7. echo %tm% %time%
  8. pause
复制代码

作者: 随风    时间: 2009-6-27 11:47

我想是找到问题原因了
bb.txt 每行一个邮箱地址,共122530行
分别作了以下测试,证明设置大量的变量不但耗费内存,而且及其影响效率。
代码一、耗时 0 小时 0 分钟 18 秒 21 毫秒
  1. @echo off
  2. set t=%time%
  3. echo. >nul 3>888.txt
  4. for /f "delims=" %%a in (bb.txt)do (
  5.    set ".asklfjkaldfjajfafd@.fjaa=i"
  6.    echo %%a
  7. )
  8. echo. >nul 4>con
  9. call time0
  10. pause
复制代码

代码二、直到内存报警还未出结果
  1. @echo off
  2. set t=%time%
  3. for /f "delims=" %%a in (bb.txt)do set ".%%a=i"
  4. call time0
  5. pause
复制代码

测试环境xp sp2 内存512m  Celeron(R) cpu 2.40GHz
.
看来7楼代码效率低是括弧用的不对,改进如下,最好请楼主再测试一下,数据更标准。
效率应该会高些,但不会有太大区别,因为最终结果888.txt的行数并不太多。
.
总的来说应该是13楼代码效率最高,因为占用内存是最少的。
其次应该就是下面的代码,
最慢的应该是11楼的。
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. (for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a
  5. )>888.txt
  6. echo %tm% %time%
  7. pause
复制代码

[ 本帖最后由 随风 于 2009-6-27 11:56 编辑 ]
作者: jackerloo2009    时间: 2009-6-27 12:07     标题: 回复 13楼 的帖子

楼上的这个用了39分26秒
作者: netbenton    时间: 2009-6-27 13:38

第一个for的if defined判断可以去掉,变量判断也是要时间的。
因为 . 号在任何系统变量的前面,加一个 . 可以免掉批处理在匹配变量时,对系统变量的扫描,可以加快速度。
其实最好是在前面加 # 号或 $  号,因为它们还要在 . 号的前面。

按楼主的数据,下面的代码应该可以提速3分钟左右。
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt) do set #%%a=i
  4. (for /f "delims=" %%a in (A.txt) do (if not defined #%%a (echo %%a)))>888.txt
  5. echo %tm% %time%
  6. pause
复制代码


2009.6.28
[更正]  “加.可以提速”的错语说法,如果使用的变量数量不是很大时,确实可以小提速,但是如果变量数量越大,就会让很多的.也占用了内存。变成得不尝失了。

我了解到:
批处理的变量在内存中的是这样连续存放的(即变量环境)

0 “变量名1”=“变量值1”0 “变量名2”=“变量值2”0 “变量名3”=“变量值3”0 。。。

并由[变量环境长度]保存所占内在的大小

当设置变量时,会先对整个变量环境进行扫描,如果已经有该变量名,则把该变量取出,其后面的变量内容前移,然后再把设置的变量及新值放在最后,再修改[变量环境长度]的值。如果环境中还没有该变量,则直接放在最后。

可以看出,每一次变量的设置及取值,都会对[变量环境]进行一次扫描,虽然内存的读取速度很快,但是随着[变量环境]的增大,需要扫描的范围也就越大,速度肯定会越慢。

所以增加的 . 会随着变量数量的增加,明显的使用[环境变量]“肥”了不少

看来,对于批处理效率来说,变量名是越短越高效的。

[ 本帖最后由 netbenton 于 2009-6-28 11:26 编辑 ]
作者: jackerloo2009    时间: 2009-6-27 13:50     标题: 回复 14楼 的帖子

你这个代码测试的时间是39分29秒
作者: 随风    时间: 2009-6-27 14:00

第一个for的if defined判断确实可以去掉,但考虑到楼主已经测试了很多代码而且耗时都不短,为了在同一起跑线,所以后面的代码都特意保留了第一个for 的 if defined
但现在看楼主的测试结果,说实话对楼主的测试环境很是怀疑。
似乎他的第一个代码效率是最高的。而从我们的理论上来说却应该是最低的~
作者: 随风    时间: 2009-6-27 14:16

不防把三个代码都编个号
代码一、
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a>>888.txt
  5. echo %tm% %time%
  6. pause
复制代码
代码二、
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. (for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a)>888.txt
  5. echo %tm% %time%
  6. pause
复制代码
代码三、
  1. @echo off
  2. set tm=%time%
  3. echo. >nul 3>888.txt
  4. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  5. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a
  6. echo. >nul 4>con
  7. echo %tm% %time%
  8. pause
复制代码
三个代码,不知道最后结果888.txt有多少行?先假设是9楼 keen 推测的2万行吧。
第一个代码和第二个代码的区别是
第一个代码只有第一个for占用了内存,但开关 i/o 2万次。
第二个代码两个for都占用了内存,但开关 i/o 1次
但这两个代码的效率却差不多,说明什么?
难道说开关 i/o 2万次 和 将2万个邮箱地址赋予内存效率是一样的?
但第三个代码的效率,楼主测试也是差不多的,这就很难理解了。
因为它也是只有第一个for占用了内存,并且也只开关 i/o 1次,怎么会效率没有区别呢?
费解~
作者: jackerloo2009    时间: 2009-6-27 14:30     标题: 回复 16楼 的帖子

测试时间39分49秒
作者: jackerloo2009    时间: 2009-6-27 14:40

我在此对于我在测试阶段的感想吧!我现在对于超长文本每次大家提供的代码我都测试,从batman最早的代码到现在,几乎每个都在40分钟测试了大概10多次了吧,个人感觉测试环境主要是机器配置的影响,跟是否浏览网页,是否还运行bat文件没有太大的关系,只要你内存足够,未满负荷,就没有太多的影响,甚至在测试自己原代码的时候,跟随风谈到ping的问题,曾开了另外3个cmd窗口测试ping的时间问题,结果最后顶楼我那个原始代码的测试时间还是最短的,曾截图发在群里时间为:37 分39秒,当然如果哪位有时间,我仍希望cpu内存足够的空机做测试,以便于更接近于科学,顺便证明一下以上我说的是否正确,毕竟一切都在于研究探索发现嘛
作者: 随风    时间: 2009-6-27 14:42

总结了下楼主的测试结果,按19的编号。
代码一、40分钟06秒
代码二、39分29秒
代码三、39分26秒
.
netbenton 16楼的代码 39分49秒
减少了122530次 if defined 判断,但效率却反而更慢了~
难道是因为16楼多用了两对多余的括弧?
这两对括弧比122530次 if defined 判断还要耗时?
越发费解~
作者: zqz0012005    时间: 2009-6-27 14:51

虽然只开关一次I/O,但仍然是边输出边写入文件。
可以推知,只启用一次IO时,并不是将输出缓存到内存,等到全部输出结束后再一次性写入文件。
如果楼主的测试可信的话,似乎可以得知:可能开关I/O消耗的时间极短,主要耗时花在通过I/O进行数据传输和写文件,尤其是写文件。
作者: Batcher    时间: 2009-6-27 14:52

  1. gawk "NR==FNR{a[$1]++}NR>FNR&&!a[$1]++" b.txt a.txt>c.txt
复制代码
第三方命令行工具 gawk.exe 下载地址:
http://bbs.bathome.net/thread-1114-1-1.html
作者: zqz0012005    时间: 2009-6-27 15:01

做测试的同时干其他事情是有影响的。
如果你把bat窗口最小化了,或者正在操作对内存消耗大的程序,影响更大。系统会自动对后台运行的任务进行优化以节约内存。
作者: jackerloo2009    时间: 2009-6-27 15:01     标题: 回复 24楼 的帖子

还是第三方强大,1秒就ok了
作者: jackerloo2009    时间: 2009-6-27 15:02     标题: 回复 25楼 的帖子

我对于一直做这么多相同的测试,并不赞同你的观点,我个人感觉影响微小
作者: jackerloo2009    时间: 2009-6-27 15:23

等下我重启机器不开任何东西,做0负荷的测试,就我原代码那个进行测试,原来的时间为37分39秒
测试完以后,我会上来发布测试结果,以真实数据来证明到底其他环境有多大影响



不好意思,大家久等了,我重启机器,所有的程序网页都没开,只是单纯测试我的原代码
测试的时间为 37分26秒

跟我想象的一样,只是差了13秒,从总体时间来考虑,也就是开其它程序,网页,或者bat对结果的影响是微小的!

[ 本帖最后由 jackerloo2009 于 2009-6-27 16:26 编辑 ]
作者: tireless    时间: 2009-6-27 15:32

用括号括起来进行输出确实是一行一行输出,可以这样验证:
  1. @echo off
  2. (
  3.   echo a
  4.   pause 打开 output.txt 会发现已经输出了 a 和 pause 的提示。
  5.   echo b
  6. ) > output.txt
复制代码

作者: 随风    时间: 2009-6-27 15:53     标题: 回复 24楼 的帖子

!a[$1]++

百思不得其解,能解释下么?
作者: jackerloo2009    时间: 2009-6-27 18:15     标题: 回复 5楼 的帖子

测试结果显示,去掉p*[email].tournois@chello.fr[/email]中的星号,它一切都是正常的,但是去掉它中的点,保留星号,就出问题了,说明问题是在星号上,而不是你说的点上
作者: zqz0012005    时间: 2009-6-27 18:30

点和星号在正则表达式中都有特殊意义。如果不加/L参数,会产生问题。

对于楼主的问题,无论是用findstr还是设置变量法,都不能很好的解决。最好是用第三方工具或其他方法。
findstr 的问题看看我8楼的回复并运行一下就知道。
至于设置变量法,如果文本中含有等号,也会出现问题。
  1. echo a=b>1.txt
  2. for /f "delims=" %%a in (1.txt) do set .%%a=1
  3. for /f "delims=" %%a in (1.txt) do if not defined .%%a echo %%a
复制代码
此帖的方向转到关于效率的讨论倒是不错。
作者: jackerloo2009    时间: 2009-6-27 18:52     标题: 回复 32楼 的帖子

最后结果显示 a=b
这是对还是不对?
呵呵,倒真是见识了batcher第三方工具的厉害。1秒钟搞定
作者: zqz0012005    时间: 2009-6-27 19:07     标题: 回复 33楼 的帖子

LZ似乎忘了自己的问题。。。
假如888.txt中有a=b,而555.txt也有,那你的要求是不需要输出,而现在却输出了,这不就是问题吗??
作者: jackerloo2009    时间: 2009-6-27 19:18     标题: 回复 34楼 的帖子

其实我那俩文本里面有=的例子oriana=-du_7141@hotmail.com
现在去测试,确实两个都有的,它都生成到888里面去了
作者: skuny    时间: 2010-12-31 22:27     标题: 回复 8楼 的帖子

findstr 不是令人丧失信心了嘛!!

离不开findstr怎么办?




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