title: Extracting specific lines (based on the line number) using batch file
body: <p>I have a need to extract specific lines from a text file (input.txt). I have already found a solution but have some clarifications why it is not working when used with <code>setlocalenabledealyed expansion</code>. Below is the example</p>
  
  <p>My <strong>input.txt</strong> <code>(numbered using findstr /n)</code>. In this example, I need to extract the lines between line number 27 to 39. In my full batch file, these values are called from another module.</p>
  
  <pre><code>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]
  </code></pre>
  
  <p>1st code - <strong>calling.bat</strong> - using <code>CALL</code></p>
  
  <pre><code>@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
  </code></pre>
  
  <p>2nd code - <strong>local.bat</strong> used with <code>setlocalenabledelayedexpansion</code></p>
  
  <pre><code>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
  </code></pre>
  
  <p>OUTPUT - <strong>Calling.bat</strong> works absolutely fine. But <strong>local.bat</strong> does not return any error, but it iterates the for loop only once. (I tried replacing !st_ln! &amp; !end_ln! with %st_ln% &amp; %end_ln%, but still the same issue) Why? What am I missing?</p>
  
  <pre><code>C:\Temp&gt;calling.bat
  NJ35CG5D9DEYXKMQKBJX
  ZAZRMGB2E0KAG85FSPI3
  E9046AQL44LV1R79OT8E
  8OPXV1QYCTQVK34JZ2KV
  3E32PWHGX5RGTFUXI9GC
  H7DTDDFQZVGETGL764YU
  174UOQMW35BCIQJNR1P8
  7B3V0E9QXFQOM3NF08CZ
  QH6FZVMKKGHKF0J8PB5O
  QCRC90QCWWGAHRWBVMUI
  4QPVEJW75GFW8DUM1PGU
  
  C:\Temp&gt;local.bat
  
  C:\Temp&gt;REM @echo OFF
  
  C:\Temp&gt;set st_ln=27
  
  C:\Temp&gt;set end_ln=39
  
  C:\Temp&gt;SETLOCAL ENABLEDELAYEDEXPANSION
  
  C:\Temp&gt;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&gt;(
  set "ln=1"
   set "sid=[root]"
   if !ln! LEQ !st_ln! goto :eof
   if !ln! GEQ !end_ln! goto :eof
   echo.!sid!
  )
  
  C:\Temp&gt;
  </code></pre>
  
  <h2>Supplementary Question :</h2>
  
  <p>As I said above, I could get the expected result, but just want to know if it can be enhanced. I want to extract specific lines (lines could be anywhere in input file and number of line I need could be 1 to 20), from the input file which could have up to 3000 lines. Currently in the above code I am using the for loop and checking the line number for each line and so it will iterate through the for loop for 3000 times, which could potentially delay the output. Is there any other way to avoid this and to speed up the script (may be findstr 'range' search)?</p>