批处理脚本读取连续写入的文件

时间:2013-02-12 09:49:59

标签: windows batch-file

我有一个连续使用此类信息编写的文件

  

HU /根/ TCFG /目标/哈辛托/起动器/ 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%”之前提取任何内容并添加它

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

有人可以帮忙吗?

由于

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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