Пример Джеба очень интересный, но очень сильно зависит от длины добавляемого или удаляемого текста. Я думаю, что нелогичные результаты - это то, что имел в виду Обман, когда он сказал: «Если вы измените его раньше, он начнет делать странные вещи (повторять команды и т. Д.)».
Я изменил код jeb, чтобы показать, как динамический код различной длины можно свободно модифицировать в начале исполняемого пакетного файла, пока имеется соответствующее заполнение. Весь динамический раздел полностью заменяется каждой итерацией. Каждая динамическая строка имеет префикс без помех ;
. Это удобно для FOR /F
удаления динамического кода из-за неявной опции EOL=;
.
Вместо того, чтобы искать конкретный номер строки, я ищу конкретный комментарий, чтобы определить, где начинается динамический код. Это легче поддерживать.
Я использую строки знаков равенства для безвредного заполнения кода для расширения и сжатия. Можно использовать любую комбинацию следующих символов: запятая, точка с запятой, равно, пробел, табуляция и / или символ новой строки. (Конечно, заполнение не может начинаться с точки с запятой.) Знаки равенства в скобках позволяют расширять код. Знаки равенства после скобок допускают сжатие кода.
Обратите внимание, что FOR /F
убирает пустые строки. Это ограничение может быть преодолено с помощью FINDSTR, чтобы префикс каждой строки с номером строки, а затем вырезать префикс в цикле. Но дополнительный код замедляет работу, поэтому делать это не стоит, если код не зависит от пустых строк.
@echo off
setlocal DisableDelayedExpansion
echo The starting filesize is %~z0
:loop
echo ----------------------
::*** Start of dynamic code ***
;set value=1
::*** End of dynamic code ***
echo The current value=%value%
::
::The 2 lines of equal signs amount to 164 bytes, including end of line chars.
::Putting the lines both within and after the parentheses allows for expansion
::or contraction by up to 164 bytes within the dynamic section of code.
(
call :changeBatch
==============================================================================
==============================================================================
)
================================================================================
================================================================================
set /p "quit=Enter Q to quit, anything else to continue: "
if /i "%quit%"=="Q" exit /b
goto :loop
:changeBatch
(
for /f "usebackq delims=" %%a in ("%~f0") do (
echo %%a
if "%%a"=="::*** Start of dynamic code ***" (
setlocal enableDelayedExpansion
set /a newValue=value+1, extra=!random!%%9
echo ;set value=!newValue!
for /l %%n in (1 1 !extra!) do echo ;echo extra line %%n
endlocal
)
)
) >"%~f0.tmp"
::
::The 2 lines of equal signs amount to 164 bytes, including end of line chars.
::Putting the lines both within and after the parentheses allows for expansion
::or contraction by up to 164 bytes within the dynamic section of code.
(
move /y "%~f0.tmp" "%~f0" > nul
==============================================================================
==============================================================================
)
================================================================================
================================================================================
echo The new filesize is %~z0
exit /b
Вышеописанное работает, но все намного проще, если динамический код перемещается в подпрограмму в конце файла. Код может расширяться и сокращаться без ограничений и без необходимости дополнения. FINDSTR намного быстрее чем FOR / F удаляет динамическую часть. Динамические строки можно смело ставить перед точкой с запятой (включая метки!). Затем опция FINDSTR / V используется для исключения строк, начинающихся с точки с запятой, и новый динамический код можно просто добавить.
@echo off
setlocal DisableDelayedExpansion
echo The starting filesize is %~z0
:loop
echo ----------------------
call :dynamicCode1
call :dynamicCode2
echo The current value=%value%
call :changeBatch
set /p "quit=Enter Q to quit, anything else to continue: "
if /i "%quit%"=="Q" exit /b
goto :loop
:changeBatch
(
findstr /v "^;" "%~f0"
setlocal enableDelayedExpansion
set /a newValue=value+1, extra=!random!%%9
echo ;:dynamicCode1
echo ;set value=!newValue!
echo ;exit /b
echo ;
echo ;:dynamicCode2
for /l %%n in (1 1 !extra!) do echo ;echo extra line %%n
echo ;exit /b
endlocal
) >"%~f0.tmp"
move /y "%~f0.tmp" "%~f0" > nul
echo The new filesize is %~z0
exit /b
;:dynamicCode1
;set value=33
;exit /b
;
;:dynamicCode2
;echo extra line 1
;exit /b