如何使用/ f在“当前”行暂停

时间:2019-02-26 23:26:21

标签: windows cmd

是否可以在CMD中使用for /f命令来逐步读取文件?我希望能够在文件中更改“尚未读取”的行(即尚未在循环中进行处理),但是这样做似乎没有效果。

例如,说我的文件temp.txt有三行:

one
# two
# three

我用

for /f "eol=#" %i in (temp.txt) do @echo %i & sleep 10s

当我执行此操作,然后在前十秒内删除井号并保存文件时,我没有得到全部三行(正如我期望的/正在寻找的)。我期望这是因为我删除了哈希标记(在开始的10秒钟之内),直到循环到达第二行时,因为没有哈希标记,它不会跳过它。似乎在处理第一行之前就先读取了整个文件(或者可能是其中的“大”块?)。有没有一种方法可以使循环仅在“使用”时才读取每一行(即不预读,而只是等到它准备好用于下一行时)?

1 个答案:

答案 0 :(得分:0)

for /Floop似乎一次读取整个文本文件 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读取了文件,但更改未反映在输出中;尽管此行为可能有大小限制,但我仍无法找到;修改文本文件的应用程序在这里也发挥了作用,因为它实际上可能在临时副本而不是给定文件上起作用,因此可能得出错误的结论。