Reputation: 39
I'm writing a batch file where I need to pick the newest of several import files that can be anywhere in a set of folders and copy it somewhere else for further processing. The directory tree looks like this:
Most days, but not every day, an import file lands into the folder structure above, in the folder with the corresponding date. The file is one of many, naming convention is [customerID]_[random number].xml, for example 94443_20152245.xml
I've tried using the FOR command:
FOR /F "delims=|" %%I IN ('DIR "c:\import\94443*.xml" /B /O:D') DO SET 94443=%%I
Copy "c:\import\%94443%" "c:\somewherelse\"
However, this only works for the top folder in the folder tree. I can't use the newest date and for example tell the command to look in c:\import\20190614, because I can't be certain that the folder tree received an import file for that customer at that date, I need to get the newest regardless of the date. Any suggestions?
Upvotes: 0
Views: 66
Reputation: 39
This works perfectly:
set "srcDir=c:\import\"
set "destdir=c:\somewherelse\"
set "lastmod="
For /f "usebackq delims=" %%a in (`
powershell -NoP -C "(Get-ChildItem -Path '%srcDir%' -Filter '94443*.xml' -File -
Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1).FullName"
`) Do Set "lastmod=%%a"
If defined lastmod (
copy "%lastmod%" "%destDir%output.xml"
) else (
Echo couldn't obtain file
)
Upvotes: 0
Reputation: 79983
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
:: Just an exercise - for customers 94440..94446 (there is no data for 94446)
FOR /l %%C IN (94440,1,94446) DO (
SET "company_%%C="
rem directories in reverse-order of name (= reverse-date-order) ONLY if files named "customer_something" exist
FOR /f "delims=" %%d IN ('dir /ad /b /o-n "%sourcedir%"') DO IF EXIST "%sourcedir%\%%d\%%C_*" (
rem list in reverse-date order (FOR TESTING PURPOSES ONLY, in NAME-ORDER)
FOR /f "delims=" %%t IN ('dir /a-d /b /o-n "%sourcedir%\%%d\%%C_*"') DO IF NOT DEFINED company_%%C SET "company_%%C=%sourcedir%\%%d\%%t"
)
IF NOT DEFINED company_%%C SET "company_%%C=----Missing----"
)
:: display result
SET company_
GOTO :EOF
You would need to change the setting of sourcedir
to suit your circumstances. The listing uses a setting that suits my system.
For ease of testing, I simply applied different customer numbers to the main routine, examining a randomly-created tree of filenames.
Essentially, two steps - list the subdirectories in reverse-name order to %%d
, then process each %%d
in turn, but only if it contains data for the customer in question, assigning the first name found (/on
is In NAME order FOR TESTING - you'd use reverse-date order, /o-d
) and once the variable has been set, ignore further set
attempts using if not defined
Then display the result...
Upvotes: 1