我需要列出文件夹中包含的每个文件并生成日志(或文本文件),但是当日志文件达到200MB的大小时,生成另一个日志文件或文件文本。
目前我有以下代码(mireg.bat),但只列出文件:
forfiles /P D:files\ /M *.pdf /C "cmd /c echo @file && @echo @file %date% %time% >> D:\files\listpdf.log"
答案 0 :(得分:3)
日志文件管理的一个有用策略是将当前日志文件移动到同一目录中,如果日志文件的文件大小超过特定限制,则将* _old.log覆盖现有的* _old.log。
带注释的批处理代码示例:
@echo off
setlocal EnableExtensions
rem Check the file size of log file and move it if its more than 200 MiB.
call :CheckLogSize "D:\files\listpdf.log" 209715200
rem Other commands which append lines to log file.
endlocal
goto :EOF
rem The subroutine CheckLogSize must be called with 2 parameters: the log
rem file name without or with path as first parameter and the maximum file
rem size as second parameter.
rem Note: Windows command processor supports only 32-bit signed integers
rem which limits file size comparison to 2 GiB, i.e. 2147483647 bytes.
rem Therefore the second parameter should not be too large. It must be
rem made sure that the current file size of the log file is not exceeding
rem 2 GiB value on calling this subroutine. So better call this subroutine
rem once too often than once too rare.
:CheckLogSize
if not exist "%~1" goto :EOF
if %~z1 GTR %~2 move /Y "%~1" "%~dpn1_old%~x1" >nul
goto :EOF
我们假设日志文件D:\files\listpdf.log
大约需要4周才能超过200 MiB。
然后它被移动到D:\files\listpdf_old.log
,由于Windows只更新文件分配表,因此速度非常快。没有数据在存储介质上复制/移动。
在下一次日志写入时,会再次创建日志文件D:\files\listpdf.log
,并在接下来的几周再次增长,最高可达200 MiB。
现在,子例程中的条件再次为真,如果在此期间未手动删除,则D:\files\listpdf.log
会再次移至D:\files\listpdf_old.log
覆盖已存在的D:\files\listpdf_old.log
。
在下一次日志写入时,再次创建日志文件D:\files\listpdf.log
,依此类推。
此策略的一大优势:可以随时手动删除当前使用的日志文件以及old
版本。存储介质上永远不会有超过两个日志文件,最大存储使用量约为400 MiB,与每小时,每天,每周,每月向日志文件中写入的数据无关。
存储介质上日志文件的限制因素是当前可用的空闲存储大小,而不是日志文件的年龄或条目的年龄。因此,在我看来,最好主要关注文件大小而不是日志条目的年龄。
我经常错过日志文件中的信息,例如超过6个月之前未在日志文件中找到,这将条目的年龄限制为3个月,尽管过去3个月的日志文件只有一个文件大小30 KiB。将过去3年的日志条目保留在硬盘上没有任何问题当然没有问题,因为这个日志文件只添加了很少的条目,每个条目只需要几个字节。但是日志文件管理适用于日志条目的年龄而不是日志文件大小,导致删除旧的但有用的日志条目只是为了将大小限制为几个KiB。
答案 1 :(得分:0)
日志文件通过在文件名后附加时间戳来自动重命名自己;例如,当文件大小超过200.0 m时,会重命名。
Robocopy给出逗号向下舍入后的位置,这意味着200.00 M也可以是200 Mib + 10.23 Kib。
robocopy带来时间戳和日志文件大小的计算。
@echo off
setlocal
prompt $g$s
set "Process=dir /s d:\"
rem set size= 150.0 m
rem usage -> see SUB :Fsize
set split= 50.0 m
set "file.log=listPDF.log"
pushd "D:\files"
if errorlevel 1 exit /b %errorlevel%
call :Fsize "%split%" size.split
for /f "eol=D tokens=1-6 delims=/: " %%T in ('
robocopy /L /njh "\|" .^|find "123"')do set "TS=%%T%%U%%V-%%W%%X%%Y"
set "empty.tmp=%temp%\%TS% .."
md "\\?\%empty.tmp%"
for %%F in ("%file.log%")Do (
set "file.tmp=%%~nF-tmp%%~xF"
set "file.TS.log=%%~nF_%TS%%%~xF"
)
> "%file.tmp%" echo LOGTIME ----- %TS% -----
>>"%file.tmp%" 2>&1 (
%process%
)
for /f "skip=2tokens=6*" %%a in ('
robocopy /L /njh "%empty.tmp%\\" . /IF "%file.log%" "%file.tmp%" /nfl /ndl ^|find " 0 "
') do call :Fsize "%%b" size.out deci.mal pre
if NOT %size.out% gtr %size.split% (
echo rem "%file.log%" %deci.mal% %pre% ^< = %split%
>>"%file.log%" type nul
copy /b "%file.log%" /b +"%file.tmp%" "%file.log%"
del "%file.tmp%"
)else (
echo rem "%file.log%" %deci.mal% %pre% ^> %split%
ren "%file.log%" "%file.TS.log%"
ren "%file.tmp%" "%file.log%"
)
popD
rd "\\?\%empty.tmp%"
exit/b
rem END script
:Fsize "512.0 k" [VAR1-floating point [VAR2-to display only [VAR3-prefix]]]
rem to use with output of robocopy
rem set with decimal minimum 1/1 max b =1024
rem set with decimal minimum 1/10 max k =.9 rounded + 102.3 bytes (+ 10 %)
rem decimal minimum 1/100 max m =.99 rounded + 10.23 KiB (+ 1 %)
rem decimal minimum 1/1000 max g =.999 rounded + 1.023 MiB (+ 0,1 %)
rem 500.0 b -> 500 bytes
rem 200.5 k -> 200,5 KiB
rem 350.04 m -> 350,04 MiB
rem 1.001 g -> 1,001 GiB
rem VAR1 size.out - Binary prefix and number to floating point
rem VAR2 deci.mal - Reverse the calculation part to display only
rem VAR3 pre.fix - Reverse the calculation to add prefix
set/a p=-1,TC=10000
for %%N in (b k m g t p)Do set /a "p+=1,%%N=p"
for /f "tokens=1-3delims=. " %%A in ("%~1 0 b")Do (
set/a"pre.fix=TC*(%%C+1) + %%A"
set "deci.mal=%%A.%%B"
setlocal enabledelayedexpansion
set "FS=!pre.fix!.%%B"
for /f "tokens=1,2" %%S in ("!FS! !deci.mal!")Do (
endlocal
if NOT "%~2"=="" (set "%~2=%%S")else set "size.out=%%S"
if NOT "%~3"=="" set "%~3=%%T"
)
)
set/ax=pre.fix/TC-1
for %%s in (b k m g t p)Do 2>nul set/a"N/=(%%s-x)"||if NOT "%~4"=="" (set "%~4=%%s")else set "pre.fix=%%s"
exit /b
代码被重写了。