找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 32459|回复: 14

[文本处理] 批处理怎样提高字串替换速度?

[复制链接]
发表于 2012-7-26 23:18:16 | 显示全部楼层 |阅读模式
各位版友大家好,我想请教有关替换字串的问题,
以下这段程式码可以替换字串
  1. @ECHO OFF
  2. (for /f "tokens=1* delims=:" %%i in ('findstr /n .* %1') do (
  3. set "line=%%j"
  4. setlocal enabledelayedexpansion
  5. if "!line!"=="" (echo.!line!) else (
  6. set "line=!line:H1=H2!"
  7. echo.!line!
  8. endlocal
  9. )))>back.txt
  10. move back.txt %1
复制代码
只是这样一行一行地echo,档案超过50kb,就会开始lag,档案越大,lag越久。

如果要处理的替换只有前二十行和後十行,
请问将文本分成三区来处理会不会比较快呢?

先将A区前二十行替换完毕,
不会动到的B区用>输出到A区後面,
最後十行C区放B区後。

所以我想请问读取文本的前二十行就跳出回圈应该要怎麽写呢?
findstr /n [1-20] %1
会跑出奇怪的结果
发表于 2012-7-27 06:53:21 | 显示全部楼层
用sed或者gawk之类的会比较快
发表于 2012-7-27 07:51:55 | 显示全部楼层
  1. @ECHO OFF & setlocal enabledelayedexpansion
  2. (for /f "tokens=1* delims=:" %%i in ('findstr /n .* %1') do (
  3.     set "line=%%j"
  4.     if not "!line!"=="" (set "line=!line:H1=H2!")
  5.     echo.!line!
  6. ))>back.txt
  7. move back.txt %1
复制代码
可以简化。(setlocal移到外面不好但是为了效率移出去..)
发表于 2012-7-27 10:02:27 | 显示全部楼层
将 echo.!line! 改为 echo:!line! 能稍微提高效率,另外
  1. set "line=!line:H1=H2!"
  2. echo.!line!
复制代码
因为此时line必然不为空,所以可以简化成:
  1. echo:!line:H1=H2!
复制代码
发表于 2012-7-27 12:23:00 | 显示全部楼层
将 echo.!line! 改为 echo:!line! 能稍微提高效率,另外因为此时line必然不为空,所以可以简化成:
CrLf 发表于 2012-7-27 10:02


遗憾的是,echo:并不比echo.更高效,它们的处理方式是一样的。
发表于 2012-7-27 14:15:10 | 显示全部楼层
回复 5# Demon


    "." 会额外触发对文件名的匹配,参考:http://bbs.bathome.net/viewthread.php?tid=4831
发表于 2012-7-27 15:12:54 | 显示全部楼层
本帖最后由 Demon 于 2012-7-27 15:14 编辑
回复  Demon


    "." 会额外触发对文件名的匹配,参考:
CrLf 发表于 2012-7-27 14:15


CMD对echo. echo: echo\的处理过程是一样的。

mystrchr.png

如果在命令中发现.:\,并且CMD拓展是开启的话,就会调用GetFileAttributes函数获取文件的属性,如果文件不存在或者文件是目录的话,那么就会把.:\改成NUL;否则会当成外部命令。

GetFileAttributes.png

但是GetFileAttributes有个BUG,会把echo.当成是echo,所以如果存在以echo为名称的文件的话,GetFileAttributes会认为echo.文件是存在的,然后CMD把echo.当成外部命令,就会导致错误。

  1. cd .>echo
  2. echo.
  3. pause
复制代码
'echo.' is not recognized as an internal or external command, operable program or batch file.

  1. md echo
  2. echo.
  3. pause
复制代码
没有问题

  1. cd .>echo
  2. setlocal disableextensions
  3. echo.
  4. pause
复制代码
没有问题

在不存在echo文件或者文件夹的情况下echo. echo: echo/的处理是一样的,不存在哪个效率更高的问题;存在echo文件的话echo.会导致错误,更不存在效率问题了。

考虑效率的话,echo, echo; echo=稍微好一些(其实也就少调用了一次GetFileAttributes)。

评分

参与人数 1技术 +1 收起 理由
CrLf + 1 效率确实是一样的,感谢指正!

查看全部评分

发表于 2012-7-27 16:18:33 | 显示全部楼层
本帖最后由 CrLf 于 2012-7-27 16:19 编辑

回复 7# Demon


   
噢!这倒没想到,测试结果也确实如此,感谢指正。
不过 echo, echo; echo= 的缺陷在于无法处理 echo;/? 这种参数为 /? 的情况,因为它们都是默认分隔符
这样一来,echo[ 和 echo] 应该是既保证通用性又能避免降低效率的方案了吧
发表于 2012-7-27 16:36:40 | 显示全部楼层
回复  Demon


   
噢!这倒没想到,测试结果也确实如此,感谢指正。
不过 echo, echo; echo= 的缺陷 ...
CrLf 发表于 2012-7-27 16:18

在我这里是没有问题的。
发表于 2012-7-27 16:40:44 | 显示全部楼层
回复 8# CrLf


这里的测试有问题吗?
http://www.bathome.net/thread-4482-1-1.html
发表于 2012-7-27 16:48:26 | 显示全部楼层
回复 9# Demon


    试试 echo;/? 和 echo[/?,win7 下测试是有区别的

回复 10# forfiles


    没有什么问题啊,只是那帖子讨论的只是效率,而我们希望找到一个兼顾效率与通用性的方案
发表于 2012-7-27 16:51:55 | 显示全部楼层
回复 11# CrLf



7楼说:echo. echo: echo/的处理是一样的,不存在哪个效率更高的问题
8楼说:测试结果也确实如此
发表于 2012-7-27 17:03:58 | 显示全部楼层
回复  Demon


    试试 echo;/? 和 echo[/?,win7 下测试是有区别的

回复  forfiles


    没有 ...
CrLf 发表于 2012-7-27 16:48


哦,理解错了。
发表于 2012-7-27 17:13:27 | 显示全部楼层
回复 12# forfiles


    测试代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (. : \ ";" "[") do (
  3.         echo !time!
  4.         echo echo%%~a
  5.         (for /l %%b in (1 1 10000) do echo%%~a)>nul
  6. )
  7. echo !time!
  8. pause
复制代码
 楼主| 发表于 2012-10-2 19:53:56 | 显示全部楼层
如果要处理的替换只有前二十行和後十行,
请问将文本分成三区来处理会不会比较快呢?

先将A区前二十行替换完毕,
不会动到的B区用>输出到A区後面,
最後十行C区放B区後。


这样做超快,但超过1mb,批处理会当掉,
  1. @echo off
  2. @setlocal enabledelayedexpansion
  3. del *.txt
  4. echo %1>drive.txt
  5. (for /f "tokens=1* delims=:" %%d in ('findstr /n .* drive.txt') do (
  6. set drive=%%e"
  7. set drive=!drive:~0,2!
  8. ))
  9. (for %%f in (%*) do (
  10. call echo !drive!%%%%f
  11. )>>t1.txt)

  12. ECHO\1.HassM09 2.HassM09T 3.HassM09TOM99 4. 5.HG83
  13. ECHO\11.M09 12.M09T 13.M09TOM99 16.M8M09  18.M57
  14. set /p prog="prog is "

  15. if %prog% equ 3 (call D:\LGetCode\TransCode\HassM09TOM99.bat) else (

  16. echo\ no mode
  17. )

  18. PAUSE
  19. del *.txt
  20. del *.doc
复制代码
HassM09TOM99.bat
  1. @echo off
  2. setlocal enabledelayedexpansion

  3. (for /f "tokens=1* delims=:" %%g in ('findstr /n .* t1.txt') do (
  4. set "file=%%h"
  5. ECHO]************************************
  6. echo]starting %%h
  7. setlocal enabledelayedexpansion
  8. set "tool=%%h"
  9. set "tool=!tool:~-4,1!"
  10. set "dec=!file:~-5,1!"
  11. if !dec! gtr 9 set dec=0
  12. set num=!dec!!tool!

  13. rem *******
  14. rem First20Line
  15. rem *******
  16. echo]First20
  17.     (for /l %%a in (1 1 20) do (
  18.        set str=&set /p str=
  19.        echo]!str!
  20.     ))<%%h >First20.txt


  21. REM ***************************************************
  22. REM deal First20Line
  23. REM ***************************************************
  24. echo]dealFirst20
  25. (for /f "tokens=1* delims=:" %%i in ('findstr /n .* First20.txt') do (
  26.     set "line=%%j"
  27.     setlocal enabledelayedexpansion
  28.     if "!line!"=="" (echo\!line!) else (
  29.    for %%n in (!num!) do set "line=!line:O1000=O00%%n!"
  30.    for %%n in (!num!) do set "line=!line:O0100=O00%%n!"
  31.    for %%n in (!num!) do set "line=!line:O0001=O00%%n!"

  32.     for %%m in (!tool!) do set "line=!line:(SC POSTPROCESSOR A.I.C TAICHUNG)=T%%mM6!"
  33.      set "line=!line:/G05.1 Q1= !"
  34.     set "line=!line:.M09=.!"
  35.     for %%l in (!tool!) do set "line=!line:H1=H%%l!"
  36.     echo\!line!
  37. endlocal
  38. )))>back.txt
  39. move back.txt First20.txt

  40. rem ********
  41. rem delFirst20
  42. rem ********
  43. more +20 %%h>WithoutFirst20.txt
  44. findstr .* WithoutFirst20.txt >> First20.txt

  45. rem *********************************************************
  46. rem Last20Line
  47. rem *********************************************************
  48. echo]last20line
  49.     sort /+4096 First20.txt /o Reverse.txt
  50.     (for /l %%a in (1 1 20) do (
  51.        set str=&set /p str=
  52.        echo]!str!
  53.     ))<Reverse.txt >Last20Rev.txt
  54.     sort /+4096 Last20Rev.txt /o Last20.txt

  55. (for /f "tokens=1* delims=:" %%i in ('findstr /n .* Last20.txt') do (
  56.     set "line=%%j"
  57.     setlocal enabledelayedexpansion
  58.     if "!line!"=="" (echo\!line!) else (

  59.     set "line=!line:/G05.1 Q0= !"
  60.     set "line=!line:M30=M99!"
  61.     echo\!line!
  62. endlocal
  63. )))>back.txt
  64. move back.txt Last20.txt


  65. rem *******
  66. rem delLast20Line
  67. rem *******
  68. ECHO]delLast20Line
  69. sort /+4096 First20.txt /o ABrev.txt
  70. more +20 ABrev.txt>WithoutCrev.txt
  71. sort /+4096 WithoutCrev.txt /o WithoutC.txt
  72. findstr .* Last20.txt >> WithoutC.txt
  73. move WithoutC.txt %%h

  74. rem ********
  75. rem End Main Loop Do and For
  76. rem ********
  77. echo]%%h is done

  78. ))
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-19 15:23 , Processed in 0.024593 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表