[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

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

各位版友大家好,我想请教有关替换字串的问题,
以下这段程式码可以替换字串
  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
会跑出奇怪的结果

用sed或者gawk之类的会比较快

TOP

  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移到外面不好但是为了效率移出去..)

TOP

将 echo.!line! 改为 echo:!line! 能稍微提高效率,另外
  1. set "line=!line:H1=H2!"
  2. echo.!line!
复制代码
因为此时line必然不为空,所以可以简化成:
  1. echo:!line:H1=H2!
复制代码

TOP

将 echo.!line! 改为 echo:!line! 能稍微提高效率,另外因为此时line必然不为空,所以可以简化成:
CrLf 发表于 2012-7-27 10:02


遗憾的是,echo:并不比echo.更高效,它们的处理方式是一样的。

TOP

回复 5# Demon


    "." 会额外触发对文件名的匹配,参考:http://bbs.bathome.net/viewthread.php?tid=4831

TOP

本帖最后由 Demon 于 2012-7-27 15:14 编辑
回复  Demon


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


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



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



但是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

评分人数

    • CrLf: 效率确实是一样的,感谢指正!技术 + 1

TOP

本帖最后由 CrLf 于 2012-7-27 16:19 编辑

回复 7# Demon


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

TOP

回复  Demon


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

在我这里是没有问题的。

TOP

回复 8# CrLf


这里的测试有问题吗?
http://www.bathome.net/thread-4482-1-1.html

TOP

回复 9# Demon


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

回复 10# forfiles


    没有什么问题啊,只是那帖子讨论的只是效率,而我们希望找到一个兼顾效率与通用性的方案

TOP

回复 11# CrLf



7楼说:echo. echo: echo/的处理是一样的,不存在哪个效率更高的问题
8楼说:测试结果也确实如此

TOP

回复  Demon


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

回复  forfiles


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


哦,理解错了。

TOP

回复 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
复制代码

TOP

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

先将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. ))
复制代码
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

返回列表