Мне нужно извлечь определенные строки из текстового файла (input.txt). Я уже нашел решение, но у меня есть пояснения, почему оно не работает при использовании с setlocalenabledealyed expansion
. Ниже приведен пример
Мой input.txt (numbered using findstr /n)
. В этом примере мне нужно выделить строки между строками с 27 по 39. В моем полном пакетном файле эти значения вызываются из другого модуля.
1:[root]
2:ASKEHPPTEQWEIRAZOKXL
...
...
...
27:[parent2/child2]
28:NJ35CG5D9DEYXKMQKBJX
29:ZAZRMGB2E0KAG85FSPI3
30:E9046AQL44LV1R79OT8E
31:8OPXV1QYCTQVK34JZ2KV
32:3E32PWHGX5RGTFUXI9GC
33:H7DTDDFQZVGETGL764YU
34:174UOQMW35BCIQJNR1P8
35:7B3V0E9QXFQOM3NF08CZ
36:QH6FZVMKKGHKF0J8PB5O
37:QCRC90QCWWGAHRWBVMUI
38:4QPVEJW75GFW8DUM1PGU
39:[parent2/child3]
...
...
...
3000:[end]
1-й код - call.bat - с использованием CALL
@echo OFF
set st_ln=27
set end_ln=39
for /f "tokens=1,2 delims=:" %%a in (input.txt) do call :extract "%%a" "%%b"
goto :eof
:extract
set "ln=%~1"
set "sid=%~2"
if %ln% LEQ %st_ln% goto :eof
if %ln% GEQ %end_ln% goto :eof
echo.%sid%
goto :eof
:eof
2-й код - local.bat, используемый с setlocalenabledelayedexpansion
REM @echo OFF
set st_ln=27
set end_ln=39
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "tokens=1,2 delims=:" %%a in (input.txt) do (
set "ln=%%a"
set "sid=%%b"
if !ln! LEQ !st_ln! goto :eof
if !ln! GEQ !end_ln! goto :eof
echo.!sid!
)
:eof
ВЫВОД - Calling.bat работает абсолютно нормально. Но local.bat не возвращает ошибок, а выполняет цикл for только один раз. (Я попытался заменить! St_ln! &! End_ln! На% st_ln% &% end_ln%, но все та же проблема) Почему? Что мне не хватает?
C:\Temp>calling.bat
NJ35CG5D9DEYXKMQKBJX
ZAZRMGB2E0KAG85FSPI3
E9046AQL44LV1R79OT8E
8OPXV1QYCTQVK34JZ2KV
3E32PWHGX5RGTFUXI9GC
H7DTDDFQZVGETGL764YU
174UOQMW35BCIQJNR1P8
7B3V0E9QXFQOM3NF08CZ
QH6FZVMKKGHKF0J8PB5O
QCRC90QCWWGAHRWBVMUI
4QPVEJW75GFW8DUM1PGU
C:\Temp>local.bat
C:\Temp>REM @echo OFF
C:\Temp>set st_ln=27
C:\Temp>set end_ln=39
C:\Temp>SETLOCAL ENABLEDELAYEDEXPANSION
C:\Temp>for /F "tokens=1,2 delims=:" %a in (input.txt) do (
set "ln=%a"
set "sid=%b"
if !ln! LEQ !st_ln! goto :eof
if !ln! GEQ !end_ln! goto :eof
echo.!sid!
)
C:\Temp>(
set "ln=1"
set "sid=[root]"
if !ln! LEQ !st_ln! goto :eof
if !ln! GEQ !end_ln! goto :eof
echo.!sid!
)
C:\Temp>
Дополнительный вопрос:
Как я уже сказал выше, я мог получить ожидаемый результат, но просто хочу знать, можно ли его улучшить. Я хочу извлечь определенные строки (строки могут быть где угодно во входном файле, а количество строк, которые мне нужны, может быть от 1 до 20) из входного файла, который может содержать до 3000 строк. В настоящее время в приведенном выше коде я использую цикл for и проверяю номер строки для каждой строки, поэтому он будет повторять цикл for 3000 раз, что потенциально может задержать вывод. Есть ли другой способ избежать этого и ускорить работу скрипта (может быть поиск findstr 'range')?