1

我有一个文件不断写入这样的信息

HU/gen/tcfg/target/jacinto/starter/starter_b1.cfg

32.77 34% 141.59kB/s 0:00:00

94.64 100% 405.35kB/s 0:00:00 (xfer#60, to-check=1002/1097)

它是 rsync 工具的输出,将文件夹复制到另一个路径

我正在尝试编写一个批处理脚本来读取此文件并计算正在复制的数据总量,重点关注这一行

94.64 100% 405.35kB/s 0:00:00 (xfer#60, to-check=1002/1097)

数字 94.64 是以字节为单位的文件大小,所以我猜我应该从行中提取“100%”之前的任何内容并添加它

但我不知道如何在同时写入文件时连续读取文件

有人可以帮忙吗?

谢谢

4

2 回答 2

3

这是一个示例,展示了如何在另一个进程写入文件时读取文件。这与 jeb 显示的非常相似,只是我添加了一个通用测试来查看该过程是否完成。它假设进程在整个执行过程中保持对文件的锁定,并且还假设 20 个连续的空行表示文件结束,或者我们正在等待进程的更多输出。20 个空行阈值可以设置为适合您的任何数字。

如果进程将部分行写入文件,此解决方案可能无法正常工作。我相信,如果该过程始终在单个操作中完整地写入每一行,那么它是可靠的。此外,行的长度必须小于或等于 1021 字节,并且必须以回车、换行符结束。

@echo off
setlocal enableDelayedExpansion
set "file=test.txt"

set emptyCount=0
del "%file%

:: For this test, I will start an asynchronous process in a new window that
:: writes a directory listing to an output file 3 times, with a 5 second pause
:: between each listing.
start "" cmd /c "(for /l %%N in (1 1 3) do @dir & ping localhost -n 6 >nul) >"%file%""

:wait for the output file to be created and locked
if not exist "%file%" goto :wait

:: Now read and process the file, as it is being written.
call :read <"%file%"
exit /b

:read
set "ln="
set /p "ln="
if defined ln (

  REM Process non-empty line here - test if correct line, extract size, and add
  REM I will simply echo the line instead
  echo(!ln!

  REM Reset emptyCount for end of file test and read next line
  set /a emptyCount=0
  goto :read

) else ( REM End of file test

  REM Count how many consecutive empty lines have been read.
  set /a emptyCount+=1

  REM Assume that 20 consecutive empty lines signifies either end of file
  REM or else waiting for output. If haven't reached 20 consectutive
  REM empty lines, then read next line.
  if !emptyCount! lss 20 goto :read

  REM Test if output file is still locked by attempting to redirect an unused
  REM stream to the file in append mode. If the redirect fails, then the file
  REM is still locked, meaning we are waiting for the process to finish and have
  REM not reached the end. So wait 1 sec so as not to consume 100% of CPU, then
  REM reset count and try to read the next line again.
  REM If the file is not locked, then we are finished, so simply fall through
  REM and exit.
  (echo off 9>>"%file%")2>nul || (
     set emptyCount=0
     ping localhost -n 2 >nul
     goto :read
  )
)
exit /b
于 2013-02-12T16:28:43.120 回答
2

就像 dbenham 说的那样,可以做到,但批处理不是首选。
注意,样本将无限循环运行。
您需要根据文件内容添加中断条件。

我添加了ping ...命令以避免该进程消耗 100% CPU 时间

@echo off
setlocal disabledelayedexpansion
setlocal enableDelayedExpansion
< rsyncOutput.tmp (
  call :readData
)
echo ready
exit /b

:readDataX
set "line="
set /p line=
if defined line (
  for /f "tokens=1,2 delims= " %%a in ("!line!") do (
    if "%%b"=="100%%" echo Bytes %%a
  )
)
ping localhost -n 2 > nul
goto :readDataX
exit /b
于 2013-02-12T14:49:04.970 回答