Questo è il comportamento progettato di FOR/F - non restituisce mai righe vuote. La soluzione è utilizzare FIND o FINDSTR per prefissare la linea con il numero di riga. Se è possibile garantire che nessuna riga inizi con il delimitatore del numero di riga, è sufficiente impostare il delimitatore appropriato e mantenere i token 1 *, ma utilizzare solo il secondo token.
::preserve blank lines using FIND, assume no line starts with ]
::long lines are truncated
for /f "tokens=1* delims=]" %%A in ('type "file.txt" ^| find /n /v ""') do echo %%B
::preserve blank lines using FINDSTR, assume no line starts with :
::long lines > 8191 bytes are lost
for /f "tokens=1* delims=:" %%A in ('type "file.txt" ^| findstr /n "^"') do echo %%B
::FINDSTR variant that preserves long lines
type "file.txt" > "file.txt.tmp"
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "file.txt.tmp"') do echo %%B
del "file.txt.tmp"
preferisco FINDSTR - è più affidabile. Ad esempio, TROVA può troncare le linee lunghe - FINDSTR non è lungo quanto legge direttamente da un file. FINDSTR fa cadere lunghe righe durante la lettura da stdin tramite pipe o reindirizzamento.
Se il file può contenere righe che iniziano con il delimitatore, è necessario conservare l'intera riga con il prefisso del numero di riga, quindi utilizzare Cerca e sostituisci per rimuovere il prefisso di riga. Probabilmente vuoi ritardare l'espansione quando trasferisci il %% A in una variabile d'ambiente, altrimenti qualsiasi! sarà corrotto. Ma più tardi all'interno del ciclo è necessaria un'espansione ritardata per effettuare la ricerca e la sostituzione.
::preserve blank lines using FIND, even if a line may start with ]
::long lines are truncated
for /f "delims=" %%A in ('type "file.txt" ^| find /n /v ""') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*]=!"
echo(!ln!
endlocal
)
::preserve blank lines using FINDSTR, even if a line may start with :
::long lines >8191 bytes are truncated
for /f "delims=*" %%A in ('type "file.txt" ^| findstr /n "^"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
::FINDSTR variant that preserves long lines
type "file.txt" >"file.txt.tmp"
for /f "delims=*" %%A in ('findstr /n "^" "file.txt.tmp"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
del "file.txt.tmp"
Se non è necessario preoccuparsi di convertire il file in ASCII, allora è più efficace di far cadere il tubo e lasciare che trovare o FINDSTR aprire il file specificato come argomento, o tramite reindirizzamento.
C'è un altro problema che ignora completamente FOR/F durante il processo di lettura. Sembra strano, ma è più efficiente. Non ci sono restrizioni nell'uso dell'espansione ritardata, ma sfortunatamente ha altre limitazioni.
1) linee devono essere risolti da < CR> < LF> (questo non sarà un problema se si fa la conversione di file TYPE)
2) linee devono essere < = 1021 byte lungo (trascurando la < CR> < LF>)
3) qualsiasi carattere di controllo finale viene rimosso da ogni riga.
4) deve leggere da un file - non è possibile utilizzare una pipe. Quindi nel tuo caso dovrai usare un file temporaneo per eseguire la tua conversione ASCII.
setlocal enableDelayedExpansion
type "file.txt">"file.txt.tmp"
for /f %%N in ('find /c /v "" ^<"file.txt.tmp"') do set cnt=%%N
<"file.txt.tmp" (
for /l %%N in (1 1 %cnt%) do(
set "ln="
set /p "ln="
echo(!ln!
)
)
del "file.txt.tmp"
Nessun problema, ma sono d'accordo che sembra male. È un'opzione più affidabile di "ECHO". Ci sono situazioni oscure in cui 'ECHO' può fallire, mentre' ECHO ('non fallisce mai.Il punto di entrambe le sintassi è di consentire l'output di una riga vuota – dbenham
Puoi spiegare la riga" echo (! Ln! "? Isn ' C'è un problema con una parentesi di chiusura? Inoltre, la riga sopra manca la chiusura! char? – djangofan
Finalmente ha funzionato. La tua conoscenza in questo settore è fantastica. Grazie. – djangofan