0

I have a homemade batch script that is run every day, as a simple copy job that copies files across from a network drive to a local one. At present, the script works fine for a month but has to be edited on a monthly and annual basis in order for it to keep working since some of the files that are copied over are date dependent.

It goes like this:

for %%I in (infdb.dat infdb.ix kunde.DAT kunde.ix L170701.DAT L170701.DIA L170701.IX perso.dat perso.ix TI*FR.DAT TI*FR.IX TILKA.DAT TILKA.IX) do copy %%I C:\bbsud1\

The files L170701.DAT L170701.DIA L170701.IX are date dependent in that they are named after LYYMMxx. And I need my batch script to account for that, in that it needs to be able to tell what year and month we are in, and "place" that date in regards to those 3 files so I get the right ones depending on what month/year it is.

I have tried looking for the answer but hasn't really been able to find something easy or concrete to go on.

DangerDane
  • 11
  • 1
  • Use wildcards like `L??????.DAT L??????.DIA L??????.IX` or `L*.DAT L*.DIA L*.IX` or `L*.*` depending on which other files not to copy are in current folder on execution of this batch file. – Mofi Jul 20 '17 at 08:15
  • I can't use a wildcard like that, as it then copies over the old files as well. L170601.DAT, L170501.DAT and so on. I don't need that The system generates a new file each month and keeps the old around as a backup, so while yours is a good suggestion, it would also mean that I would be copying over all the old files that are not needed or requried. – DangerDane Jul 20 '17 at 08:20
  • 1
    Just a quick idea (not fully understanding what you need though): consuiderconsider to use [`xcopy`](http://ss64.com/nt7xcopy.html), which features a `/D` option; you may also be interested in `/U`, or `/-Y`... – aschipfl Jul 20 '17 at 08:29
  • I need the batch script to automatically "select" the proper file;L170701.DAT L170701.DIA L170701.IX for month 7, L170801.DAT L170801.DIA L170801.IX for month 8 and so forth. The year and month part of that file name is dynamic and dependent and the year and date of creation. I need the batch script to only download the current file and not all the old ones. Does that help? – DangerDane Jul 20 '17 at 08:33
  • So are you looking for **`L`** followed by `any two digits` followed by `two digit current month` followed by `any two digits` followed by **`DAT`**? If so I would suggest you search here for code which determines a non localised current month and saves it as a variable. – Compo Jul 20 '17 at 09:03
  • LYYMMDD (YY=Year, MM = Month, DD= Day.). The DD bit is just always 01 but the first 4 digits change depending on year/month – DangerDane Jul 20 '17 at 10:46

3 Answers3

0

Use wmic to get the date in a locale/user settings independent format:

@Echo off
for /f "delims=." %%A in (
  'wmic os get LocalDateTime^|findstr ^^[0-9]'
) do Set DT=%%A
Set "yymm=%DT:~2,4%"

for %%I in (
    infdb.dat infdb.ix kunde.DAT kunde.ix 
    Lc%yymm%01.DAT L%yymm%01.DIA L%yymm%01.IX 
    perso.dat perso.ix TI*FR.DAT TI*FR.IX TILKA.DAT TILKA.IX
) do copy %%I C:\bbsud1\
0

There are at least two possible solutions to get current year without century and month with two digits.

The first one is independent on region and language settings of used account.

@echo off
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocaleDateTime=%%I"
set "FileNameDate=%LocaleDateTime:~2,4%"
for %%I in (
    infdb.dat infdb.ix kunde.DAT kunde.ix
    L%FileNameDate%01.DAT L%FileNameDate%01.DIA L%FileNameDate%01.IX
    perso.dat perso.ix TI*FR.DAT TI*FR.IX TILKA.DAT TILKA.IX
) do copy %%I C:\bbsud1\ >nul 2>nul

This variant is similar to solution posted by LotPings, but is a little bit faster because of FINDSTR is not needed. Please read answer on Why does %date% produce a different result in batch file executed as scheduled task? for full explanation of the FOR loop and used WMIC command.

The disadvantage is that WMIC requires more than a second to output the local date/time.


Much faster is the second solution using environment variable DATE:

@echo off
set "FileNameDate=%DATE:~-2%%DATE:~-7,2%"
for %%I in (
    infdb.dat infdb.ix kunde.DAT kunde.ix
    L%FileNameDate%01.DAT L%FileNameDate%01.DIA L%FileNameDate%01.IX
    perso.dat perso.ix TI*FR.DAT TI*FR.IX TILKA.DAT TILKA.IX
) do copy %%I C:\bbsud1\ >nul 2>nul

The disadvantage is that this solution depends on date format defined in Windows Region and Language settings by selected country respectively the date format settings for the country.

The above code works if echo %DATE% outputs for example 20.07.2017 or Thu, 20/07/2017.

The string substitution must be modified if date format is MM/dd/yyyy without or with weekday at beginning:

set "FileNameDate=%DATE:~-2%%DATE:~-10,2%"

But a different code is necessary like the one below if a month < 10 is output without a leading 0 like Thu, 20/7/2017:

for /F "tokens=2,3 delims=./" %%I in ("%DATE:~-10%") do set "FileNameDate=%%J0%%I"
set "FileNameDate=%FileNameDate:~2,2%%FileNameDate:~-2%"

So the advantage of faster execution on using environment variable DATE requires knowledge of date format which is the reason why DATE based code is not often posted on Stack Overflow.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • copy /?
  • echo /?
  • for /?
  • set /?

Please read also the Microsoft article about Using command redirection operators for an explanation of >nul and 2>nul to suppress success and error messages output by COPY by redirecting both to device NUL.

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

There is a function that I found and I modified it to add more variables, as an example, it can even give your current Timezone. It is using the command "wmic os get LocalDateTime".

List of current variables with a short description:

- _YYYY          (Year)
- _MM            (Month)
- _DD            (Day)
- _HR            (Hour)
- _MN            (Minutes)
- _SC            (Secondes)
- _ML            (Millisecondes)

- _TIMEZONE_M    (Timezone - Minutes)
- _TIMEZONE_H    (Timezone - Hours:Minutes)

- _DATE          (YYYY-MM-DD)
- _TIME_MN       (HR:MN)
- _TIME_SC       (HR:MN:SC)

Example usage:

call :LIB_TIME

echo Date is: %_DATE%
echo Time is: %_TIME_SC%
echo.
echo Date is: %_YYYY%-%_MM%-%_DD%
echo Time is: %_HR%:%_MN%:%_SC%

Script:

:LIB_TIME

:: Usage:
::
:: Example:
:: call :LIB_TIME
:: echo Date is: %_YYYY%-%_MM%-%_DD%
:: echo Time is: %_HR%:%_MN%:%_SC%

:: PARSING TIME VALUES
FOR /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' SET ldt=%%j
SET _ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,6%

SET _RAW_TIME=%ldt%

:: VARIABLES
SET _YYYY=%ldt:~0,4%
SET _MM=%ldt:~4,2%
SET _DD=%ldt:~6,2%
SET _HR=%ldt:~8,2%
SET _MN=%ldt:~10,2%
SET _SC=%ldt:~12,2%
SET _ML=%ldt:~15,3%

:: Timezone (Minutes)
SET _TIMEZONE_M=%ldt:~-4%
SET _TIMEZONE_POL=%ldt:~-5,1%

:: Timezone (HH:MM)
SET /a "_TIMEZONE_CALC_H=_TIMEZONE_M/60"
SET /a "_TIMEZONE_CALC_M=_TIMEZONE_M%%60"
IF %_TIMEZONE_CALC_H% LSS 10 SET _TIMEZONE_CALC_H=0%_TIMEZONE_CALC_H%
IF %_TIMEZONE_CALC_M% LSS 10 SET _TIMEZONE_CALC_M=0%_TIMEZONE_CALC_M%
SET _TIMEZONE_H=%_TIMEZONE_POL%%_TIMEZONE_CALC_H%:%_TIMEZONE_CALC_M%

:: CUSTOM VARIABLES
SET _DATE=%_YYYY%-%_MM%-%_DD%
SET _TIME_MN=%_HR%:%_MN%
SET _TIME_SC=%_HR%:%_MN%:%_SC%

Goto :eof
Frank Einstein
  • 676
  • 8
  • 15