I have a batch file to retrieve files from a shared workspace.
@echo off
setlocal
for /f "tokens=*" %%f in ('dir "D:\Share" /a-d-h /b /s') do (
for /f "tokens=1,2,3" %%g in ('dir "%%f" /tc ^| findstr /C:"%%~nxf"') do (
echo %%h,%%i,%%g,"%%~nf","%%~xf
)
)>>D:\test.csv
endlocal
I would like to modify the first four output columns to:
Apologies in advance as new to this, also open to any redesign if there is a better process.
@ECHO OFF
SETLOCAL
FOR /f "delims=" %%b IN ('dir /b /s /a-d-h "xx.csv" ') DO (
ECHO %%b
FOR /f "tokens=1-3" %%g IN ('dir /tc "%%b"^|findstr /c:"%%~nxb"') DO (
CALL :report %%g %%h %%i %%~tb "%%~nb" "%%~xb"
rem CALL :report 04/30/2016 08:46 AM 08/05/2016 01:17 PM "%%~nb" "%%~xb"
)
)
GOTO :EOF
:report
rem parameters are cdate ctime campm mdate mtime mampm name extension (cdate=createdate...)
rem datestamp format is 08/05/2016 01:17 PM for Aug. 5th 2016 @ 1:17pm
rem required output format
rem Time Created HH:MM Date Created YYYY-MM.DD Last Modified HH:MM Last Modified YYYY-MM.DD name extension
CALL :YYYY-MM.DD cdate %1
CALL :24hr ctime %2 %3
CALL :YYYY-MM.DD mdate %4
CALL :24hr mtime %5 %6
ECHO %ctime% %cdate% %mtime% %mdate% %~7 %~8
GOTO :eof
:: convert from mm/dd/yyyy to YYYY-MM.dd
:YYYY-MM.DD
SET "raw=%2"
SET "%1=%raw:~-4%-%raw:~0,2%.%raw:~3,2%"
GOTO :eof
:: convert from hh:mm ampm to HH:MM
:24hr
SET "raw=%2"
rem Exx 00:17 -> 12:17; 01:17 -> 01:17; 12:17 -> 12:17; 13:17 -> 01:17
IF "%raw:~02%"=="12" (SET /a raw=100) ELSE (SET "raw=1%raw:~0,2%")
rem Exx 00:17 -> 100 ; 01:17 -> 101 ; 12:17 -> 100 ; 13:17 -> 101
IF /i "%3" == "PM" SET /a raw+=12
rem Exx 00:17 -> 100 ; 01:17 -> 101 ; 12:17 -> 112 ; 13:17 -> 113
SET "raw=%raw%%2"
rem Exx 00:17 -> 10012:17; 01:17 -> 10101:17; 12:17 -> 11212:17; 13:17 -> 11312:17
SET "%1=%raw:~1,2%%raw:~-3%"
GOTO :eof
For testing purposes, I targeted a single file and removed the appending to the report file.
The :report
subroutine takes 8 parameters - two sets of [date time ampm] and the file's name and extension. The name and extension can potentially contain spaces, so should be quoted.
it converts the dates supplied to the required format using subroutines :YYYY-MM.DD
for the date and :24hr
for the time end echo
es the results.
:YYYY-MM.DD
is simple. It assigns the date provided as the second parameter to a temporary variable, then uses substringing to deliver the required string to the variable specified as the first parameter.
Substringing is covered by set /?
from the prompt or many articles on SO. It's important to note that the first character in a string is character 0
, not 1
.
You should not use temp
or tmp
for a user-variable as BOTH of these variables contain the name of a directory used to store temporary files. In the early days, some people used tmp
and others temp
for this purpose, so setting both suits both groups and maintains compatibility.
:24hr
is a little more complex. Again %1
is used to specify the return variable name. Its schtick is to convert 12
as an hour number to 00
if the time is AM and leave it as 12
for PM. Other hours, add 12 for PM.
The gotcha here is that if left to its own devices, batch will suppress leading zeroes and regards a leading 0
as specifying the value as octal.
So - if the first 2 characters of the time are 12
, start with 100
, otherwise, start with 1
prepended to the hour (consequently, 09:xx would become 109
- valid decimal instead of 09
- invalid octal).
Then add 12 if the time is PM.
Append the original time field to the result, and pick the 2nd and third character with the last 3 for return to %1.
Since my date/time format is DD/MM/YYYY HH:MM, it will produce nonsense when processed by the :report
routine, so I tested using a set of constants as I believe they would be presented on a MM/DD/YYYY hh:mm ampm system (now remmed-out)
Further thoughts
I got wmic
to work on my Win11 system.
SETLOCAL ENABLEDELAYEDEXPANSION
SET "filepath=c:\106x"
SET "Filename=withtrailsp.txt"
set "EscapedFilePath=%FilePath:\=\\%"
FOR /f "usebackqtokens=1*delims=." %%b IN (
`%SystemRoot%\System32\wbem\wmic.exe DATAFILE where "name='%EscapedFilePath%\\%Filename%'" GET "CreationDate"^,"LastAccessed"^,"LastModified" /VALUE`
) DO IF "%%c" neq "" SET %%b
SET la
SET cr
Since it seems that wmic
is required in order to get seconds for Created
then it'll take the same amount of time to get all of the time fields using wmic
with the advantage that the format is ISO (at least it is for me)
Note that this snippet uses delayedexpansion
and that the \
in filepaths needs to be doubled. Note also that the commas in the fields list also need to be escaped. The filename is just one I knew had different create/modified/accessed dates.