У меня есть несколько странный случай, когда цикл for невероятно медленный, когда я использую findstr в качестве строки для DO.
Стоит отметить, что файл (old-file.xml
), который я 'Обработка m содержит около 200 000 строк.
Эта часть работает быстро, но может быть визуализирована медленнее, если я удаляю | 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
)
РЕДАКТИРОВАТЬ:
Дальнейшие исследования показали, что использование этой единственной строки, которая должна отображать текущий номер строки, занимает около 10 минут в моем 8-мегабайтном файле из 200 000 строк.Это просто для того, чтобы заставить его начать отображать строки.
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