Domanda

Ho bisogno di estrarre linee specifiche da un file di testo (input.txt). Ho già trovato una soluzione ma ho alcuni chiarimenti perché non funziona se utilizzato con setlocalenabledealyed expansion. Di seguito è riportato l'esempio

My Input.txt (numbered using findstr /n). In questo esempio, ho bisogno di estrarre le linee tra la linea numero 27 a 39. Nel mio file batch completo, questi valori sono chiamati da un altro modulo.

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 ° Codice - Calling.bat - Utilizzo di 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
.

2nd Codice - Local.bat Utilizzato con 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
.

Uscita - Calling.bat Funziona assolutamente bene. Ma Local.bat non restituisce alcun errore, ma itona il loop solo una volta. (Ho provato a sostituire! ST_LN! &! End_LN! Con% st_LN% &% END_LN%, ma ancora lo stesso problema) Perché? Cosa mi manca?

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>
.

Domanda supplementare:

Come ho detto sopra, potrei ottenere il risultato atteso, ma voglio solo sapere se può essere migliorato. Voglio estrarre linee specifiche (le linee potrebbero essere ovunque nel file di input e il numero di linea che ho bisogno potrebbe essere da 1 a 20), dal file di input che potrebbe avere fino a 3000 linee. Attualmente nel codice sopra riportato utilizzando il ciclo per il ciclo e il controllo del numero di riga per ciascuna riga e quindi ipererà attraverso il loop per 3000 volte, il che potrebbe potenzialmente ritardare l'output. C'è qualche altro modo per evitare questo e ad accelerare lo script (potrebbe essere la ricerca della gamma "di ricerca")?

È stato utile?

Soluzione

Il local.bat non funziona perché quando viene lezionata la prima riga, con il numero 1 e la riga di partenza 27, la condizione if !ln! LEQ !st_ln! goto :eof viene valutata come VERO e il comando goto eseguito, lasciando il loop di for.

Per la domanda supplementare, è possibile calcolare quante righe devono essere saltate all'inizio del file e quindi è possibile eseguire solo la linea finale.Poiché nessuna variabile viene modificata all'interno del loop, non è necessario alcuna necessità di espansione ritardata

set /a "skipLines=st_ln-1"
if %skipLines% gtr 0 ( 
    set "skipLines=skip=%skipLines%" 
) else ( 
    set "skipLines=" 
)


for /f "%skipLines% tokens=1,2 delims=:" %%a in (input.txt
) do if %%a gtr %end_ln% ( goto :eof ) else ( 
    echo(%%b
)
.

Il test if %skiplines% gtr 0 è necessario in quanto il loop for /f non consente una clausola skip=0

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top