Parse a log file's last modified date into a v

2019-09-21 03:00发布

问题:

I am trying to set a variable to the number of days since a log file was modified. this way I can use that value as a flag for the next time a command runs.

example:

if the command ran yesterday, the value will be 1

if the command ran 5 days ago, the value will be 5

I'm seeing methods for similar issues such as:

OR %%f IN (%filename%) DO SET filedatetime=%%~tf

or

if (file.exists()) {
  Date lastModified = new Date(file.lastModified());
}

I just don't know batch scripting or powershell very well. I'm open to running this script in either. I think what I need to learn is:

1) extract the (tokens?) sub string of just the date from a date/time modified command

2) removing any colons or slashes

3) convert to an integer

4) repeat for today's date

Once I have two integers subtracting and setting a variable should be easy.

Any recommendations?

回答1:

In PowerShell you can just subtract one date from another and get a timespan. So something as simple as:

$File = Get-Item C:\Path\To\File.txt
$DaysSinceMod = [datetime]::now - $File.LastWriteTime | Select -Expand Days

Then $DaysSinceMod would be how many days since the file was last modified. Or, using some shorthand, that can be reduced to:

$LastMod=(get-date)-(gi C:\Path\To\File.txt)|% Days


回答2:

Using a Batch file, you may convert a date into a Julian Day Number in a very simple way via a conversion "function", and then use the number in any way you wish:

@echo off
setlocal EnableDelayedExpansion

rem Define the "Date to Julian Day Number" conversion function
set "DateToJDN(YMD)=( a=(YMD), y=a/10000, a%%=10000, m=a/100, d=a%%100, a=(m-14)/12, (1461*(y+4800+a))/4+(367*(m-2-12*a))/12-(3*((y+4900+a)/100))/4+d-32075 )"

rem Get the JDN of today's date
for /F "tokens=1-3 delims=/" %%a in ("%date%") do set /A "today=!DateToJDN(YMD):YMD=%%c%%a%%b!"

rem Get the JDN of each file, subtract it from today's JDN and show the elapsed days
for %%f in (*.csv) do for /F "tokens=1-3 delims=/ " %%a in ("%%~Tf") do (
   set /A "daysOld=today - !DateToJDN(YMD):YMD=%%c%%a%%b!"
   echo !daysOld!  -  %%f
)

For example, using these files:

07/04/2018  07:45 p. m.               135 data.csv
07/04/2018  07:45 p. m.                79 data_1.csv
07/04/2018  07:45 p. m.                65 data_2.csv
06/02/2018  07:41 p. m.               104 file1.csv
03/06/2017  06:02 p. m.             5,534 file2.csv
14/04/2018  10:49 p. m.             2,674 HCT_ACT_01.csv
14/04/2018  10:49 p. m.               714 HCT_ACT_02.csv
14/04/2018  10:49 p. m.             2,010 HCT_ACT_03.csv
21/03/2018  09:15 p. m.               313 msource1.csv
21/03/2018  09:16 p. m.               402 msource2.csv
21/03/2018  09:16 p. m.               402 msource3.csv
06/10/2017  09:18 p. m.               156 output.csv
03/06/2017  06:11 p. m.             2,017 Reconresult.csv
21/03/2018  09:41 p. m.               491 result.csv
20/12/2017  12:25 a. m.               305 source.csv

This is the output:

135  -  data.csv
135  -  data_1.csv
135  -  data_2.csv
195  -  file1.csv
443  -  file2.csv
128  -  HCT_ACT_01.csv
128  -  HCT_ACT_02.csv
128  -  HCT_ACT_03.csv
152  -  msource1.csv
152  -  msource2.csv
152  -  msource3.csv
318  -  output.csv
443  -  Reconresult.csv
152  -  result.csv
243  -  source.csv

Note: the data of the files shown use the DD/MM/YYYY date format, but the code is correct for MM/DD/YYYY date format. If your format is different, just adjust the %%c%%a%%b part in the code.



回答3:

Dates can be subtracted in PowerShell. The result is a [System.TimeSpan].

PS C:\src\t> $(Get-Date) - $(Get-Item -Path 'sw.txt').LastWriteTime


Days              : 193
Hours             : 23
Minutes           : 36
Seconds           : 44
Milliseconds      : 168
Ticks             : 167602041681449
TotalDays         : 193.983844538714
TotalHours        : 4655.61226892914
TotalMinutes      : 279336.736135748
TotalSeconds      : 16760204.1681449
TotalMilliseconds : 16760204168.1449

PS C:\src\t> ($(Get-Date) - $(Get-Item -Path 'sw.txt').LastWriteTime).Days
193

If you want to do this in a .bat or .cmd script:

@ECHO OFF
SET "THEFILE=C:\src\t\sw.txt"
FOR /F %%a IN ('powershell -NoProfile -Command ^
    "((Get-Date) - (Get-Item -Path "%THEFILE%").LastWriteTime).Days"') DO (SET /A "NDAYS=%%a")
ECHO Days since "%THEFILE%" has been written is %NDAYS%