检查文件是否超过2分钟

时间:2015-04-17 08:27:04

标签: batch-file executable

我想检查一个文件" test.txt"超过两分钟。

到目前为止,我可以检查机器的当前时间戳和文件的上次修改日期。

但是现在如何从当前机器时间减去检查文件是否超过两分钟?

set mytimestamp="%date:~0,2%.%date:~3,2%.%date:~6,4% 

%time:~0,2%:%time:~3,2%"

echo %mytimestamp%

SET filename="test.txt"
FOR %%f IN (%filename%) DO SET filedatetime="%%~tf"
::echo %filedatetime%


IF %filedatetime% == %mytimestamp% goto same

goto notsame


:same
ECHO "files same"
goto :eof

:notsame 
ECHO "files not same"
goto :eof


:eof

3 个答案:

答案 0 :(得分:2)

像往常一样,我过分关注。

dt2epoch.bat - Unix纪元的本地日期/时间(1970-01-01 00:00:00 UTC后的秒数)

@echo off
setlocal enabledelayedexpansion

if "%~1" equ "" (echo.dt2epoch.bat: usage: missing {year}.& exit /b 1)
if "%~2" equ "" (echo.dt2epoch.bat: usage: missing {month}.& exit /b 1)
if "%~3" equ "" (echo.dt2epoch.bat: usage: missing {day}.& exit /b 1)
if "%~4" equ "" (echo.dt2epoch.bat: usage: missing {hour}.& exit /b 1)
if "%~5" equ "" (echo.dt2epoch.bat: usage: missing {minute}.& exit /b 1)
if "%~6" equ "" (echo.dt2epoch.bat: usage: missing {second}.& exit /b 1)
if "%~7" neq "" (echo.dt2epoch.bat: usage: too many arguments.& exit /b 1)

set year=%~1
set month=%~2
set day=%~3
set hour=%~4
set minute=%~5
set second=%~6

rem remove leading zeroes, which set /a stupidly takes as octal (see <http://stackoverflow.com/questions/14762813/remove-leading-zeros-in-batch-file>)
for /f "tokens=* delims=0" %%i in ("!year!") do set year=%%i
for /f "tokens=* delims=0" %%i in ("!month!") do set month=%%i
for /f "tokens=* delims=0" %%i in ("!day!") do set day=%%i
for /f "tokens=* delims=0" %%i in ("!hour!") do set hour=%%i
for /f "tokens=* delims=0" %%i in ("!minute!") do set minute=%%i
for /f "tokens=* delims=0" %%i in ("!second!") do set second=%%i
rem echo.!year!-!month!-!day! !hour!:!minute!:!second!

rem get the (negative of the) local time zone offset
set i=0
for /f "delims=" %%i in ('w32tm /tz') do (
    set line[!i!]=%%i
    set /a i+=1
)
set /a ntzo=!line[0]:~-28,-24!
if "!line[0]:~0,40!" equ "Time zone: Current:TIME_ZONE_ID_DAYLIGHT" set /a ntzo+=!line[2]:~-28,-25!
rem echo.ntzo=!ntzo!

rem month days and cumulative past month days lookup
set MDAYS[1]=31
set MDAYS[2]=28
set MDAYS[3]=31
set MDAYS[4]=30
set MDAYS[5]=31
set MDAYS[6]=30
set MDAYS[7]=31
set MDAYS[8]=31
set MDAYS[9]=30
set MDAYS[10]=31
set MDAYS[11]=30
set MDAYS[12]=31
set CPMDAYS[1]=0
set /a CPMDAYS[2]=MDAYS[1]
set /a CPMDAYS[3]=CPMDAYS[2]+MDAYS[2]
set /a CPMDAYS[4]=CPMDAYS[3]+MDAYS[3]
set /a CPMDAYS[5]=CPMDAYS[4]+MDAYS[4]
set /a CPMDAYS[6]=CPMDAYS[5]+MDAYS[5]
set /a CPMDAYS[7]=CPMDAYS[6]+MDAYS[6]
set /a CPMDAYS[8]=CPMDAYS[7]+MDAYS[7]
set /a CPMDAYS[9]=CPMDAYS[8]+MDAYS[8]
set /a CPMDAYS[10]=CPMDAYS[9]+MDAYS[9]
set /a CPMDAYS[11]=CPMDAYS[10]+MDAYS[10]
set /a CPMDAYS[12]=CPMDAYS[11]+MDAYS[11]

set /a pastLeapDays=(year-1968)/4-(year-1900)/100+(year-1600)/400
if "!month!" equ "0" (set leap=0) else if "!month!" equ "1" (set leap=0) else if "!month!" equ "2" (set leap=0) else (set /a leap="!(year%4)-!(year%100)+!(year%400)")
set /a cpmDays=CPMDAYS[!month!]
set /a epoch=((((year-1970)*365+pastLeapDays+cpmDays+leap+day-1)*24+hour)*60+minute+ntzo)*60+second
rem echo.!epoch! (pastLeapDays=!pastLeapDays! cpmDays=!cpmDays! leap=!leap! ntzo=!ntzo!)

echo.!epoch!

exit /b 0

epoch.bat - 当前日期/时间的Unix纪元

@echo off
setlocal enabledelayedexpansion

if "%~1" neq "" (echo.epoch.bat: usage: too many arguments.& exit /b 1)

call dt2epoch.bat !date:~0,4! !date:~5,2! !date:~8,2! !time:~0,2! !time:~3,2! !time:~6,2!

exit /b 0

modepoch.bat - 用于文件修改时间戳的Unix纪元

@echo off
setlocal enabledelayedexpansion

if "%~1" equ "" (echo.modepoch.bat: usage: missing {filename}.& exit /b 1)
if "%~2" neq "" (echo.modepoch.bat: usage: too many arguments.& exit /b 1)

if not exist "%~1" (echo.modepoch.bat: usage: file "%~1" does not exist.& exit /b 1)

set dt=%~t1
set year=!dt:~0,4!
set month=!dt:~5,2!
set day=!dt:~8,2!
set hour=!dt:~11,2!
set minute=!dt:~14,2!
rem unfortunately, file mod timestamp doesn't come with seconds; just set to zero
set second=00

call dt2epoch.bat !year! !month! !day! !hour! !minute! !second!

exit /b 0

modage.bat - 自文件修改时间戳

以来经过的秒数
@echo off
setlocal enabledelayedexpansion

if "%~1" equ "" (echo.modage.bat: usage: missing {filename}.& exit /b 1)
if "%~2" neq "" (echo.modage.bat: usage: too many arguments.& exit /b 1)

set fileName=%~1
if not exist "!fileName!" (echo.modage.bat: usage: file "!fileName!" does not exist.& exit /b 1)

for /f %%i in ('epoch.bat') do set epoch=%%i
for /f %%i in ('modepoch.bat "!fileName!"') do set modepoch=%%i

set /a diff=epoch-modepoch
echo.!diff!

exit /b 0

checkage.bat - 测试文件(修改)是否大于或小于给定的秒数

@echo off
setlocal enabledelayedexpansion

if "%~1" equ "" (echo.checkage.bat: usage: missing {filename}.& exit /b 1)
if "%~2" equ "" (echo.checkage.bat: usage: missing {age}.& exit /b 1)
if "%~3" neq "" (echo.checkage.bat: usage: too many arguments.& exit /b 1)

set fileName=%~1
if not exist "!fileName!" (echo.checkage.bat: usage: file "!fileName!" does not exist.& exit /b 1)
set age=%~2

for /f %%i in ('modage.bat "!fileName!"') do set modage=%%i

set /a diff=modage-age
if "!diff:~0,1!" neq "-" goto older
goto younger

:older
echo.older
goto eof

:younger
echo.younger
goto eof

:eof
exit /b 0

这些脚本目前正在基于相当多的测试工作在我的系统上,但必须提到一些警告:

  • epoch.bat脚本硬编码系统!date!!time!格式的假设,可以在控制面板中配置(至少!date!是) 。例如,我将日期格式设置为yyyy-MM-dd,但是IIRC,这不是默认格式。如果格式不同,则必须调整子字符串扩展。
  • modepoch.bat脚本硬编码%~t1返回的文件修改时间戳格式的假设。我相信同样的警告适用于此处日期/时间格式的可配置性。
  • 正如您在modepoch.bat中看到的那样,%~t1未返回秒,而我无法让系统返回秒。因此,我不得不为秒字段硬编码零。这可能会导致modage.bat脚本出现一些奇怪的行为;具体来说,如果你触摸一个文件,然后立即获得它的年龄,你可以得到0到59之间的任何东西,因为脚本被迫假设文件是​​在最后一次修改的开始时间(秒= 0)被修改了。
  • 作为dt2epoch.bat的一部分,我尝试通过解析w32tm /tz的输出来获取当前的本地时区偏移量。这是从本地时间转换为UTC所必需的,因为Unix纪元定义为自1970-01-01 00:00:00 UTC 以来的秒数。毋庸置疑,这可能是此代码中非常脆弱的组成部分。此外,它从该实用程序的输出中看到,其输出下面的时区数据可以支持一定程度的灵活性,我不打算尝试在我的代码中解析(坦率地说,可能不会能够使用纯Dosbatch,就此而言)。例如,看起来可能存在标准时间偏差,并且可能对于单个时区可能存在多于两个(即,不仅仅是标准和日光)时区偏移。但是我的代码只解析基本时区偏移量和额外的日光时间偏移量,并对这些输出行进行了一些非常严格的假设。代码的这个特定组件可能不适合您。幸运的是,你可以很容易地摆脱它,虽然结果的纪元值不会完全准确,但是这些不准确的值之间的比较应该仍然是正确的。

尽管有上述所有(相当重要的)警告,但此代码在我当前的系统中对我有用;我的Unix(Cygwin)date实用程序(特别是date +%s)与epoch.bat的输出之间达成了完美的协议,修改时间戳和比较内容似乎也正常工作

如果胆敢的话,请使用此代码。

答案 1 :(得分:1)

通常这样做的方法是将两次转换为时间坐标,(常规数值表示时间作为时间单位的数量,比如分钟,因为过去的固定时间点,称为“ epoch“,)从第二个时间坐标减去所需的偏移量(在你的情况下为2分钟),然后将两个时间坐标作为数字进行比较。

不幸的是,采用Windows日期和时间命令给出的文本(人类可读)时间戳并将其转换为时间坐标非常困难。即使你经历了提取年份数,月份数,日期,小时和分钟的所有麻烦,并将所有这些连接成看起来像数字的东西,你仍然无法对待它就像一个数字,因为例如从201504170001减去2得到201504169999,而不是201504162359。

因此,为了使其工作,您必须使用数字乘法和加法而不是字符串连接,这意味着您必须将年份数乘以一年中的分钟数,并将其添加到月份数字乘以一个月内的分钟数,然后将其添加到月中乘以一天中的分钟数,依此类推,但为了做到这一点,您首先必须知道是否每个月有30天或31天,并且由于2月份可能有28天或29天这取决于是否是闰年这一事实而变得更加复杂。

所以,我会说,忘记它。这不是Windows批处理文件中合理的做法。用真实的编程语言编写一个小程序,或者找到一种方法来完成你想要做的事情,而不必检查文件的时间戳是否超过一段时间。

答案 2 :(得分:1)

这应该有效:

set hh=%TIME:~0,2%
set mm=%TIME:~3,2%
set ss=%TIME:~6,2%

set /a sum_sec=%hh% * 3600 + %mm% * 60 + %ss% -120

set /a h=%sum_sec% / 3600
set /a m=(%sum_sec%/60) - 60 * %h%
set /a s=%sum_sec% - 60 * (%sum_sec%/60)
IF %h% LSS 10 set h=0%h%
IF %m% LSS 10 set m=0%m%
IF %s% LSS 10 set s=0%s%

set new_time=%h%:%m%:%s%

forfiles /P "C:\SomePath" /S /M test.txt /C "cmd /c if @ftime LSS %new_time% del /F /Q @path"

在此示例中,如果文件test.txt超过2分钟,我们将删除该文件。您可以通过将120替换为任何其他值(以秒为单位)来改变行set /a sum_sec=%hh% * 3600 + %mm% * 60 + %ss% -120中的时间。