[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
  做这个题目的时候,又想起了以前在其他论坛曾经帮别人解答过类似的题目,有位网友给出了一段十分经典的代码,用的是 for /l + findstr正则+sort 方案,只需要设置两个变量即可搞定,处理海量数据的速度只能用震惊来形容,处理顶楼的数据,排序部分花了不到两秒钟(机器配置:主频1.6G、内存512M、操作系统XP_SP3)。呵呵,先卖个关子,请大家继续。

  用顶楼的数据来测试我那个 for /l + findstr 的猜想,等了快10分钟都还没得到最终结果,看来cmd.exe对频繁调用某些命令可能有一些抑制机制,以防非正常的调用导致系统崩溃——当然,这只是我的一个猜想,各位可以当做是我在为自己可耻的失败寻找冠冕堂皇的理由^_^。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

12楼的临时文件可省略
后面sort也可弃去 直接SET ..等同了
JM版的FINDSTR  总觉得是整行获取  那不是后面还要很多工作

[ 本帖最后由 terse 于 2009-2-26 17:38 编辑 ]

TOP

set再for
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd.>b.txt
  4. for /f "delims=" %%a in ('type a.txt') do for %%i in (%%a) do set number=____%%i&set !number:~-5!=1
  5. for /f "delims=_=" %%i in ('set _^|sort') do (
  6.   set var=!var! %%i
  7.   set /a n+=1
  8.   set /a "i=1/(n/6)" 2>nul && (>>b.txt echo !var!&set var=&set n=)
  9. )
  10. (echo !var!)>>b.txt%不足6个数的部分%
  11. start b.txt
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

for /l + findstr (有临时文件)
  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd.>b.txt
  4. (for /f "delims=" %%a in ('type a.txt') do for %%i in (%%a) do echo %%i)>~a.txt
  5. (for /l %%a in (1 1 9999) do echo %%a)>~t.txt
  6. for /f %%a in ('findstr /rxg:~a.txt t.txt') do (
  7.   set var=!var! %%a
  8.   set /a n+=1
  9.   if !n!==6 (>>b.txt echo !var!&set var=&set n=)
  10. )
  11. (echo !var!)>>b.txt%不足6个数的部分%
  12. del ~a.txt ~t.txt
  13. start b.txt
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

  for /l+findstr+sort 方案需要生成临时文件,临时文件是一行一条数据,然后想办法sort,需要用findstr的正则来控制要提取的数字的位数,如何控制参与sort的数字的位数是这个方案的关键,暂时就提示那么多,看看有没有人能写出成形的代码。

  呵呵,貌似这个题目弄成挑战赛了。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

用临时文件的话 我直接TYPE
FINDSTR 控制位数的话 好象用.的话的通配了  再想想
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "usebackq tokens=*" %%i in ("n.txt") do (
  3.     for %%j in (%%i) do (
  4.         set "str=   %%j"
  5.         echo !str:~-4!
  6. )))>tem
  7. for /f "tokens=*" %%i in ('sort tem') do (
  8.   set/a n+=1,n%%=6
  9.   if !n! equ 0 (echo !var:~1! %%i&set "var=")else set var=!var! %%i
  10. )
  11. if not "!var!"=="" echo !var:~1!
  12. pause
复制代码

[ 本帖最后由 terse 于 2009-2-26 21:04 编辑 ]
1

评分人数

    • namejm: 很有技巧性,高。PB + 10

TOP

海量数据用临时文件加findstr
少量数据用变量
我只能想到这样了。。

[ 本帖最后由 随风 于 2009-2-26 19:26 编辑 ]
技术问题请到论坛发帖求助!

TOP

我最多就这思路了  貌似比上面麻烦  继续看看
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "usebackq tokens=*" %%i in ("n.txt") do (
  3.     for %%j in (%%i) do echo %%j
  4. ))>tem
  5. for /l %%i in (1 1 4) do (
  6. if "!t!"=="" (set t=[0-9])else set t=[0-9]!t!
  7. for /f %%i in ('findstr "\<!t!\>" tem^|sort') do (
  8.     set/a n+=1,n%%=6
  9.     if !n! equ 0 (echo !var:~1! %%i&set "var=")else set var=!var! %%i
  10. )
  11. )
  12. if not "!var!"=="" echo !var:~1!
  13. pause
复制代码

TOP

set 变量法补 0 时也可以用其他符号如 +、# 或 $ 等。

总的想法与楼主一样,也是先 SET 变量(用来排序)再 FOR(用来输出)。

TOP

  terse在17楼的代码思路也非常不错,如果第二条for语句不使用type语句而直接sort的话,效率还可以稍有提升。

  23楼的思路正是我提到的 for /l+findstr+sort 方案,与17楼的方案比起来,在速度上差远了。

  就目前情况而言,17楼的方案应该是最通用、也是效率最高的了。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

回复 21楼 的帖子

'type tem^|sort' 为何不写成  sort tem
技术问题请到论坛发帖求助!

TOP

原帖由 随风 于 2009-2-26 20:31 发表
'type tem^|sort' 为何不写成  sort tem

这就改  谢

TOP

忍不住,也发两个凑凑热闹。
代码一、
不生成临时文件,适合处理少量数据。可以处理重复数字。
  1. @echo off
  2. if "%~1"=="" (
  3.   setlocal enabledelayedexpansion&set /a n=0
  4.   for /f "tokens=* delims=0" %%a in ('%~s0 h^|sort') do (
  5.      set /a n+=1,n=n%%6
  6.      set /p=%%a <nul
  7. if !n! equ 0 echo.
  8.    )
  9.   pause&exit
  10. )
  11. setlocal enabledelayedexpansion
  12. for /f "usebackq tokens=*" %%i in ("a.txt") do (
  13.    for %%j in (%%i) do set m=0000000000%%j&echo !m:~-10!
  14. )
  15. endlocal
  16. goto :EOF
复制代码
代码二、
需确定最高位是多少。
生成一个临时文件也可以,不过既然已经生成了临时文件,不防再多生成一个以提高效率。
因为 for /f + findstr 效率很低。
适合处理海量数据。
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "usebackq tokens=*" %%i in ("a.txt") do (
  3.     for %%j in (%%i) do echo %%j
  4. ))>tem
  5. sort tem>tem2
  6. cd.>tem
  7. for /l %%a in (1 1 4) do (
  8.    set num=.!num!
  9.    findstr /x !num! tem2>>tem
  10. )
  11. for /f "delims=" %%a in (tem) do (
  12.      set /a n+=1,n=n%%6
  13.      set /p=%%a <nul
  14. if !n! equ 0 echo.
  15. )
  16. echo.&pause
复制代码
1

评分人数

    • namejm: 好代码,一出就是两个。PB + 10
技术问题请到论坛发帖求助!

TOP

为23楼加点注释以便初学者阅读

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. ::把原始数据转换成每行只有一个数字的形式
  4. (for /f "usebackq tokens=*" %%i in ("a.txt") do (
  5.   for %%j in (%%i) do (
  6.     echo %%j
  7.   )
  8. ))>tem
  9. ::分别对一位、二位、三位、四位数字进行sort排序
  10. ::这样的做的原因是sort排序时是按照字符ASCII逐位比较的
  11. for /l %%i in (1 1 4) do (
  12.   if "!t!"=="" (
  13.     ::定义这样的变量是为了在后面的findstr正则表达式中匹配任意一位0到9之间的数字
  14.     set t=[0-9]
  15.   ) else (
  16.     ::在后面的findstr正则表达式中分别匹配二位、三位、四位数字
  17.     set t=[0-9]!t!
  18.   )
  19.   ::控制参与sort排序的数字位数
  20.   ::在findstr正则表达式中<string>表示精确匹配
  21.   ::结合外层for循环实现分别对一位、二位、三位、四位数字进行sort排序
  22.   for /f %%i in ('findstr "\<!t!\>" tem^|sort') do (
  23.     set /a n+=1
  24.     ::对6取余是实现六列一行的关键
  25.     set /a n%%=6
  26.     if !n! equ 0 (
  27.       echo !var:~1! %%i
  28.       set "var="
  29.     ) else (
  30.       set var=!var! %%i
  31.     )
  32.   )
  33. )
  34. if not "!var!"=="" (
  35.   echo !var:~1!
  36. )
复制代码
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

为21楼加点注释以便初学者阅读

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. ::把原始数据转换成每行只有一个数字的形式
  4. (for /f "usebackq tokens=*" %%i in ("a.txt") do (
  5.   for %%j in (%%i) do (
  6.     ::在每个数字的最左侧补上三个空格
  7.     set "str=   %%j"
  8.     ::截取补空格以后的字符串的最右侧四位
  9.     ::最终的结果就是把所有数字全部补成四个字符(不足四位的在左侧补空格)
  10.     ::这样的做的原因是sort排序时是按照字符ASCII逐位比较的
  11.     echo !str:~-4!
  12.   )
  13. ))>"%temp%\GridNum.txt"
  14. ::利用tokens=*忽略行首空格的特性来删除前面补的空格
  15. for /f "tokens=*" %%i in ('sort "%temp%\GridNum.txt"') do (
  16.   set /a n+=1
  17.   ::对6取余是实现六列一行的关键
  18.   set /a n%%=6
  19.   if !n! equ 0 (
  20.     echo !var:~1! %%i
  21.     set "var="
  22.   ) else (
  23.     set var=!var! %%i
  24.   )
  25. )
  26. if not "!var!"=="" (
  27.   echo !var:~1!
  28. )
复制代码
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表