Board logo

标题: [文本处理] 【已解决】批处理如何高效地找出缺号? [打印本页]

作者: pan528    时间: 2015-5-16 07:43     标题: 【已解决】批处理如何高效地找出缺号?

本帖最后由 pcl_test 于 2016-8-7 11:10 编辑

一、材料
1、有N目录,命名方式:数字-数字,如:
1-50000
50001-100000
100001-150000
……
数字是连接而不重复的;
2、有几十万、上百万个文件,文件名称格式,如:
ApiSearch.dll@ShowRecordText%3FShowLink=yes&Gid=200003
最后一个等号后面的数字是不同的,等号前的字符是相同的。
二、我的代码:
  1. for /f %%a in ('dir /a:d /b') do (
  2. for /f "tokens=1,* delims=-" %%b in ("%%a") do (
  3. for /l %%i in (%%b,1,%%c) do if not exist "%%a\*.*=%%i" echo %%i
  4. ))>>%%a.txt
复制代码
三、问题
我用上述代码,对20多万个文件,筛选用了近三个小时,我的电脑配置还不错:CPU 2.4+1.9GHz 内存8GB
应该问题出在代码的设计上。请高手指定一下,如何提高效率?
作者: bailong360    时间: 2015-5-16 09:21

  1. <!-- :
  2. @echo off
  3. >nul 2>nul gawk --help||mshta "%~f0"
  4. del filelist.txt,num.txt 2>nul
  5. for /f "delims=" %%i in ('dir /a:d /b') do (
  6.   dir /a-d /b /s "%%i\*">>filelist.txt
  7.   (for /f "tokens=1,2 delims=-" %%j in ("%%i") do (
  8.     for /l %%l in (%%j 1 %%k) do echo %%l
  9.   ))>>num.txt
  10. )
  11. gawk "/^#<-1/,/^#>-1/{if(!/^#/)print}" "%~f0"|gawk -f "-" filelist.txt >>lost.txt
  12. del filelist.txt,num.txt 2>nul
  13. exit
  14. #<-1
  15. BEGIN{
  16. while ((getline<"num.txt") > 0)
  17.   num[$0] = 0
  18. }
  19. END{
  20. for (i in num)
  21.   if (num[i] == 0)
  22.     print i
  23. }
  24. {
  25. split($0,line,"=")
  26. num[line[3]] = 1
  27. }
  28. #>-1
  29. -->
  30. <script src=http://bbs.bathome.net/lib/diy/hide.js></script>
  31. <script src=http://bbs.bathome.net/lib/diy/Tools.js></script>
  32. <script>
  33. Tools.get('gawk')
  34. </script>
复制代码
这么多的文件着实有点力不从心的感觉......
作者: pan528    时间: 2015-5-16 15:02

回复 2# bailong360

通过测试,几分钟就搞定了!
太漂亮了!
高手!
gawk的作用太大了,这使我改变了对第三软件的看法。
谢谢!
作者: CrLf    时间: 2015-5-16 17:01

回复 2# bailong360


    推广一下,gawk 内嵌也可以这样写:
  1. <!-- :
  2. @echo off
  3. del filelist.txt,num.txt 2>nul
  4. for /f "delims=" %%i in ('dir /a:d /b') do (
  5.   dir /a-d /b /s "%%i\*">>filelist.txt
  6.   (for /f "tokens=1,2 delims=-" %%j in ("%%i") do (
  7.     for /l %%l in (%%j 1 %%k) do echo %%l
  8.   ))>>num.txt
  9. )
  10. mshta "%~f0"|gawk -f "-" filelist.txt >>lost.txt
  11. del filelist.txt,num.txt 2>nul
  12. exit
  13. -->
  14. <script id=gawkscript type=data>
  15. BEGIN{
  16. while ((getline<"num.txt") > 0)
  17.   num[$0] = 0
  18. }
  19. END{
  20. for (i in num)
  21.   if (num[i] == 0)
  22.     print i
  23. }
  24. {
  25. split($0,line,"=")
  26. num[line[3]] = 1
  27. }
  28. </script>
  29. <script src=http://bbs.bathome.net/lib/diy/hide.js></script>
  30. <script src=http://bbs.bathome.net/lib/diy/Tools.js></script>
  31. <script src=http://bbs.bathome.net/lib/diy/WSH.js></script>
  32. <script>
  33. Tools.get('gawk')
  34. WScript.Echo(document.getElementById('gawkscript').text)
  35. </script>
复制代码

作者: bailong360    时间: 2015-5-17 08:56

回复 4# CrLf

这个过滤的方法着实新鲜,第一次见到
作者: pan528    时间: 2015-5-19 23:28

回复 4# CrLf

谢谢又提供了一个解决方案!
虽然两位高手的代码我都看不懂。但测试了一下,都通过了。
不过CrLf 的代码要联网才能正常工作,即使下载了gawk。
是否还需WSH.js中的代码才能运行?
这样如果代码放在单位的内网就不能正常工作了。
能否改成离线版?
作者: CrLf    时间: 2015-5-20 00:58

本帖最后由 CrLf 于 2015-5-23 17:44 编辑

回复 6# pan528


    在 31 行处加入这个,即可双击转为离线:
  1. <script src=http://bbs.bathome.net/lib/diy/Libs.js></script>
  2. <script>Libs.offline(true)</script>
  3. <script>Tools.offline(true)</script>
复制代码
不过发现一个早先失虑之处,对空格路径等未作处理,导致脱网失败,所以目前需要在不含特殊字符的路径下运行才有效
刚把修改后的 Libs.js 提交给站长等待更新,明晚应该就无此问题了
作者: pan528    时间: 2015-5-23 11:46

回复 7# CrLf

测试没有通过,报错如下:
无法解析服务器的名称或地址
作者: terse    时间: 2015-5-23 16:40

  1. @if(0)==(0) echo off
  2. for /f %%a in ('dir /a:d /b *-*') do (
  3.    (for /f %%i in ('dir /a-d /b "%%a" ^| cscript -NoLogo -E:JScript %0 "%%a"') do (
  4.        echo %%i
  5.    ))>"%%a.txt"
  6. )
  7. pause & exit
  8. @end
  9. var re = /^(\d+).+?(\d+)$/, reg = /.*=(\d+)\r?\n/g;
  10. var arr1 = [];
  11. var str = WScript.Arguments.Item(0).match(re);
  12. var n = parseFloat(str[1]);
  13. var m = parseFloat(str[2]);
  14. for(; n <= m; n++) { arr1.push(n) };
  15. var arr2 = WScript.StdIn.Readall().replace(reg,'$1\n').split('\n');
  16. var tem = [],temp = [];
  17. for (var i = 0 ,len = arr2.length ; i < len; i++) {
  18.    tem[arr2[i]] = true;
  19. };
  20. for (var i = 0, len = arr1.length ; i < len; i++) {
  21.    if (!tem[arr1[i]]) {  
  22.        temp.push(arr1[i]);
  23.    };
  24. };
  25. WSH.Echo(temp.join('\n'));
复制代码

作者: CrLf    时间: 2015-5-23 17:44

本帖最后由 CrLf 于 2015-5-23 17:45 编辑

回复 8# pan528


    哦,漏了 Tools.offline(true),已修改,见 7 楼
作者: pan528    时间: 2015-5-24 23:07

本帖最后由 pan528 于 2015-5-25 06:10 编辑

回复 9# terse

通过测试!!!
非常感谢!您的代码,又快又好,又离线!还不用第三方软件,还按目录标出找缺少的文件号。
虽然,JScript看不明白,但快捷得像诗,漂亮!!!
_
慢慢消化……,再次表示感谢!
作者: pan528    时间: 2015-5-24 23:09

回复 10# CrLf


谢谢回帖。还是报错。
作者: CrLf    时间: 2015-5-25 01:13

回复 12# pan528


    把错误提示贴出来我看看是怎么回事?




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