是否可以在CMD中使用for /f
命令来逐步读取文件?我希望能够在文件中更改“尚未读取”的行(即尚未在循环中进行处理),但是这样做似乎没有效果。
例如,说我的文件temp.txt有三行:
one
# two
# three
我用
for /f "eol=#" %i in (temp.txt) do @echo %i & sleep 10s
当我执行此操作,然后在前十秒内删除井号并保存文件时,我没有得到全部三行(正如我期望的/正在寻找的)。我期望这是因为我删除了哈希标记(在开始的10秒钟之内),直到循环到达第二行时,因为没有哈希标记,它不会跳过它。似乎在处理第一行之前就先读取了整个文件(或者可能是其中的“大”块?)。有没有一种方法可以使循环仅在“使用”时才读取每一行(即不预读,而只是等到它准备好用于下一行时)?
答案 0 :(得分:0)
for /F
loop似乎一次读取整个文本文件 1 。要查看给定文件的任何更改,需要打开和关闭该文件以读取每一行。无论如何,您还必须考虑可以插入或删除行,因此输出可能与您期望的不一样。
以下代码应做您想要的-查看所有解释性的rem
注释:
@echo off
rem // Define file path/name here:
set "FILE=%~dpn0.txt"
rem // Determine number of lines - 1:
for /F %%C in ('^< "%FILE%" find /C /V ""') do set /A "CNT=%%C-1"
rem // Iterate through all 0-based line numbers:
for /L %%I in (0,1,%CNT%) do (
rem // Wait for some time:
> nul timeout /T 3 /NOBREAK
rem // Read a single line in a sub-routine:
call :SUB "%FILE%" %%I
)
exit /B
:SUB
rem // Prepare `skip` option for `for /F` loop (to skip current line number - 1):
if %~2 equ 0 (set "SKIP=") else (set "SKIP=skip=%~2")
rem /* Read single line; `findstr` prefixes them with a line number to preserve
rem empty lines (remember that `for /F` skips them otherwise, so letting them
rem alone would lead to `for /F` returning the next non-empty line): */
for /F "%SKIP% delims=" %%L in ('findstr /N "^" "%~1"') do (
rem // Store the read line, including the line number prefix:
set "LINE=%%L"
rem // Exit the loop, hence skip the rest of the file:
goto :END
)
:END
rem /* Return the read line with the line number prefix removed;
rem delayed expansion avoids trouble with special characters: */
setlocal EnableDelayedExpansion
(
for /F "delims= eol=#" %%K in ("!LINE:*:=!") do endlocal & echo(%%K
) || endlocal
exit /B
此脚本遵循某些行号,因此:
1)我尝试了一个包含64K行的文件,每个行的长度为8K,更改了最后一行,同时让for /F
读取了文件,但更改未反映在输出中;尽管此行为可能有大小限制,但我仍无法找到;修改文本文件的应用程序在这里也发挥了作用,因为它实际上可能在临时副本而不是给定文件上起作用,因此可能得出错误的结论。