0

I need to get the modification date of a file stored in a variable like this: YearMonthDayHourMinute. So 01/21/2019 9:12 AM would be 201901210912. What I will be doing is comparing files to see which is newer, so it needs to be like this in 24 hour format. I was initially going to get it with this command: for %? IN ("%cd%\out.txt") do (echo %~t?) and use the for loop to split the output apart, but I was wondering if the modification date from a for loop is locale dependent like %date%? If it is, is there a way to check which type of format it is under, or is there a way to get a non-locale dependent modification date?

This is related to Why wont this function's variables set? Batch Code but I don't see how solving one would necessarily alter the other one, so I'm keeping them as separate questions.

Mark Deven
  • 1,618
  • Hi Mark - How about wmic datafile where name="C:\\folder\\folder\\File.txt" get LastModified /format:list or something like that. I think you do not want AM/PM format though and you want 00-24 format on the YYYYMMDDhhmm string format. Maybe this can work for you and you can iterate loop the file with a FOR /R loop for something for the file name and path. Just a quick idea for you just in case. – Vomit IT - Chunky Mess Style Jan 22 '19 at 03:49
  • No Instance(s) Available. I was able to convert AM/PM into a number (AM is 1, PM is 2) and put it before the time so it still applies as a larger number. – Mark Deven Jan 22 '19 at 13:38
  • For some reason, the WMIC needs to use two backslashes like it needs to escape the character or whatever. Be sure the full file path uses two forward slashes between the folder paths otherwise, you will need to cd /d to the dir and then specify the file name only I think. – Vomit IT - Chunky Mess Style Jan 22 '19 at 13:41
  • Are you strictly limited to batch scripts? Windows also comes with PowerShell, JScript, VBScript. – u1686_grawity Jan 22 '19 at 13:41
  • I was already in the same directory of the file, I'll try using the full path with double quotes.

    I can't use PowerShell for security reasons, but JScript and VBScript would be fine.

    – Mark Deven Jan 22 '19 at 14:18
  • The wmic command worked well. I can probably manipulate a Path string to replace \ with \\ so it can handle it, then parse it into that command. – Mark Deven Jan 22 '19 at 16:09
  • I'm actually getting the error C:\\Users\\theBATeam\\CMDS.bat - Invalid alias verb. Any ideas as to what that means? My script is: https://pastebin.com/raw/qvLwygB3 – Mark Deven Jan 22 '19 at 16:59
  • I never knew about that.... I think a fix is mentioned here using call per the rojo answer but you could also consider just piping the command output to a file and then reading the content of the file to set as the variable and then delete the file. Not sure how many files or if the total overhead would be too much but that's another quick thought. – Vomit IT - Chunky Mess Style Jan 22 '19 at 23:38
  • the for loop isn't running when I do that. It successfully outputs it into a file but: For /f "tokens=1,2* delims==" %%a in (out.temp) do set %~2=%%b does nothing. If I make it For /f "tokens=1,2* delims==" %%a in (out.temp) do echo hello it never echos hello. – Mark Deven Jan 24 '19 at 17:07

1 Answers1

1
set _ForString=%~1
set _ForString=!_ForString:\=\\!
For /f "tokens=1,2* delims==" %%a in ('wmic datafile where name="!_ForString!" get LastModified /format:list') do (
  echo %%a    %%b
  set %~2=%%b
)

Rem %1 is set to C:\Users%username%\CMDS.bat

I'm actually getting the error C:\\Users\\theBATeam\\CMDS.bat - Invalid alias verb.

There are two problems in the above code snippet:

  • in name="!_ForString!": you need to escape the equals sign as name^="!_ForString!";
  • parsing wmic output in a FOR /F loop (explained below).

:ParseWmicDatafile subroutine in the following commented .bat script should do the job:

@ECHO OFF
SETLOCAL EnableExtensions

call :ParseWmicDatafile "%~f0" LastModified
REM show all variables prefixed with an underscore
set _

goto :eof

:ParseWmicDatafile
REM inputs (by value): %1 is a fully qualified file name 
REM                    %2 is a valid "wmic datafile" property name

REM outputs (by reference): _%~2 is a variable name drawn from supplied %2: 
REM                              property name prefixed with an underscore
REM                         _ForString

  REM remove residuary variable _%~2 (if present)
  if defined _%~2 set "_%~2="
  set "_ForString=%~1"
  set "_ForString=%_ForString:\=\\%"
  for /f "tokens=1* delims==" %%A in (
      'wmic datafile where name^="%_ForString%" get %~2 /format:list'
    ) do for /f "delims=" %%b in ("%%~B") do (
        echo %%A    %%b
        set "_%~2=%%b"
    )
goto :eof

Here the for loops are

  • %%A to retrieve the LastModified property name (%%A) and value (%%B);
  • %%b to remove the ending carriage return in the value returned; wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).

See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem

Output:

==> D:\bat\SU\1396664.bat
LastModified    20190201220347.477320+060
_ForString=D:\\bat\\SU\\1396664.bat
_LastModified=20190201220347.477320+060

==>
JosefZ
  • 13,217