Основано на решении Джои, это только для безопасной обработки всех специальных символов %&|<>"
, а также !^
.
Это только необходимо, если вы ожидаете !
в данных вашего файла.
В любом другом случае код Джои лучше и легче для чтения.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Initialize the variables we are going to use to avoid using stale environment vars
set LIST=
set COUNT=0
rem Iterate over the lines in the text file
rem We need toggling the delayed expansion inside the loop
rem always disabled if using %%l, enabled for using the variables
for /f "delims=" %%l in (list.txt) do (
rem Append the current line to the list, %%l is only safe if delayed expansion is disabled
set "line=%%l"
setlocal EnableDelayedExpansion
rem To use the line variable, delayed expansion has to be enabled
for %%a in ("!LIST!!line!") do (
endlocal
set "LIST=%%~a"
)
set /a COUNT+=1
rem Count how many we got
rem If we have five items already
setlocal EnableDelayedExpansion
if !COUNT! GEQ 5 (
rem Output them and reset the list
echo(!LIST!
endlocal
set "LIST="
set COUNT=0
) ELSE (
endlocal
)
)
setlocal EnableDelayedExpansion
rem Output the remainder if the list does not contain k×5 lines
if defined LIST echo(!LIST!
Почему это так сложно?
Проблема в том, что %% a (переменные FOR-Loop-Variables) раскрываются непосредственно перед выполнением отложенного расширения. У вас возникают проблемы, если содержимое %% a содержит !
, а затем вы теряете также ^
(только если существует один или несколько !
).
Но вам нужно отложенное расширение, чтобы показать или сравнить содержимое переменных внутри цикла for (забудьте о вызове %% var %%).
Расширение с задержанным синтаксисом! Переменная! всегда безопасен, не зависит от содержимого, так как это последний этап синтаксического анализатора.
Но, к сожалению, включение / отключение отложенного опыта. всегда создает новый контекст переменной, при выходе из этого контекста вы теряете все изменения переменных.
Поэтому я использую внутренний цикл FOR-Loop для перехода от enabledDelayed-Context обратно к disabledDelayed-Context, поэтому LIST-var содержит правильные данные.
надеюсь, кто-то понимает, что я пытаюсь объяснить.
Еще несколько объяснений о фазах можно найти в как сценарии синтаксического анализа cmd.exe