我有一個有點奇怪的情況下,當我使用findstr作爲DO的字符串for循環是非常慢。緩慢處理循環,利用findstr
值得一提的是,我正在處理的文件(old-file.xml
)包含大約200000行。
這部分是極快的,但如果我刪除| find /c ":"
rem find total number of lines in xml-file
findstr /n ^^ old-file.xml | find /c ":" > "temp-count.txt"
set /p lines=< "temp-count.txt"
的代碼是緩慢的這個樣子的,我不能使用管道上面的技巧可以呈現慢。看起來慢的部分是for
本身,因爲直到10分鐘後我纔在標題欄中看到任何進展。
setlocal DisableDelayedExpansion
rem start replacing wrong dates with correct date
for /f "usebackq Tokens=1* Delims=:" %%i in (`"findstr /n ^^ old-file.xml"`) do (
rem cache the value of each line in a variable
set read-line=%%j
set line=%%i
rem restore delayed expansion
setlocal EnableDelayedExpansion
rem write progress in title bar
title Processing line: !line!/%lines%
rem remove trailing line number
rem set read-line=!read-line:*:=!
for /f "usebackq" %%i in ("%tmpfile%") do (
rem replace all wrong dates with correct dates
set read-line=!read-line:%%i=%correctdate%!
)
rem write results to new file
echo(!read-line!>>"Updated-file.xml"
rem end local
endlocal
)
編輯:
進一步調查顯示我使用應顯示當前的行號繞環這個單行承擔的200萬行我8MB文件約10分鐘。這只是爲了讓它開始顯示線條。
for /f "usebackq Tokens=1* Delims=:" %%i in (`"findstr /n ^^ old-file.xml"`) do echo %%i
所以好像findstr
被寫入屏幕輸出對用戶隱藏了,但可見的for
-loop。我怎樣才能防止這種情況發生,同時仍然得到相同的結果?
編輯2:解決方案
提議Aacini最後由我修訂的解決方案。
這是一個更大的腳本片段。在另一個循環中檢索錯誤的日期。並且還從另一個循環中檢索總行數。
setlocal enabledelayedexpansion
rem this part is for snippet only, dates are generated from another loop in final script
echo 2069-04-29 > dates-tmp.txt
echo 2069-04-30 >> dates-tmp.txt
findstr /n ^^ Super-Large-File.xml > out.tmp
set tmpfile=dates-tmp.txt
set correctdate=2011-11-25
set wrong-dates=
rem hardcoded total number of lines
set lines=186442
for /F %%i in (%tmpfile%) do (
set wrong-dates=!wrong-dates! %%i
)
rem process each line in out.tmp and loop them through :ProcessLines
call :ProcessLines < out.tmp
rem when finished with above call for each line in out.tmp, goto exit
goto ProcessLinesEnd
:ProcessLines
for /L %%l in (1,1,%lines%) do (
set /P read-line=
rem write progress in title bar
title Processing line: %%l/%lines%
for %%i in (%wrong-dates%) do (
rem replace all wrong dates with correct dates
set read-line=!read-line:%%i=%correctdate%!
)
rem write results to new file
echo(!read-line:*:=!>>"out2.tmp"
)
rem end here and continue below
goto :eof
:ProcessLinesEnd
echo this should not be printed until call has ended
:exit
exit /b
什麼文件有你的'old-file.xml'?你可以嘗試在循環中添加一個'echo我活着的',看看'findstr'是否是問題 – jeb
'old-file.xml'包含200 000行,大小約爲8 MB。我在for循環中使用'title'而不是'echo我活着' – NiklasJ