简体   繁体   中英

Creating multiple files using batch

I'm trying to generate multiple files for a specific situation, but my loop statement does not work properly. The batch file have three entries, such as:

Unit code = e.g (095)
Initial date = e.g (20211001)
Final date =  e.g (20211010)

I'm expecting 10 files, like this. Because from the initial date until the final date we have 10 days, in this example, but could be 15, 20...

2v09520211001.rep
2v09520211002.rep
2v09520211003.rep
2v09520211004.rep

My code

Echo off        
cls
color 1f
title Bat automatiza 2V
:menu
Time /t
Date /t
echo *********************************
echo * Automatize files generate     *
echo *********************************
set /p op= Unit code
set /p op1= Initial date
set /p op2= Final date
for(int i = %op1%; i < %op2%; i++) {
    do 
    echo > 2v%op%%op1%%op2%.rep
}

Thank you in advance.

Here is a complete code with reading the data from a text file or prompting the user of the batch file for the date with validating the data before using the data to create the empty files with the appropriate file names.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Undefine the three environment variables used to hold the data.
set "UnitCode="
set "InitialDate="
set "FinalDate="

rem Load the data from file Data.txt in batch file directory if existing.
if exist "%~dp0Data.txt" for /F "usebackq tokens=1,2* delims== " %%G in ("%~dp0Data.txt") do set "%%G%%H=%%~I"
if defined UnitCode set "UnitCode=%UnitCode:"=%"
if defined InitialDate set "InitialDate=%InitialDate:"=%"
if defined FinalDate set "FinalDate=%FinalDate:"=%"

rem Check each value and prompt user on value not defined or invalid.
call :CheckValue UnitCode "unit code" ".[0123456789][0123456789]*." 0 "%UnitCode%"
call :CheckValue InitialDate "initial date in format 20yyMMdd" ".20[0123456789][0123456789][01][0123456789][0123][0123456789]." 1 "%InitialDate%"
call :CheckValue FinalDate "final date in format 20yyMMdd" ".20[0123456789][0123456789][01][0123456789][0123][0123456789]." 1 "%FinalDate%"

rem Check if the initial date is before or equal the final date.
if %InitialDate% LEQ %FinalDate% goto CreateFiles
echo ERROR: The initial date %InitialDate% is after the final date %FinalDate%!
goto :EOF

:CheckValue
if "%~5" == "" goto GetValue
set "Value=%~5"
goto ValidateValue

:GetValue
set "Value="
set /P "Value=Please enter %~2: "
if not defined Value goto GetValue
set "Value=%Value:"=%"
if not defined Value goto GetValue

:ValidateValue
setlocal EnableDelayedExpansion
rem The value must match the regular expression or it is invalid.
echo "!Value!"| %SystemRoot%\System32\findstr.exe /R /X %3 >nul
if errorlevel 1 (
    echo ERROR: !Value! is not valid for %~2^^!
    endlocal
    goto GetValue
)
endlocal
set "%1=%Value%"
if %4 == 0 goto :EOF

rem Additional checks for validating a date value.
set "Year=%Value:~0,4%"
set /A Month=1%Value:~4,2% - 100
set /A Day=1%Value:~6,2% - 100
if %Month% == 0 goto InvalidDate
if %Month% GTR 12 goto InvalidDate
if %Day% == 0 goto InvalidDate
if %Day% GTR 31 goto InvalidDate
for %%I in (1 3 5 7 8 10 12) do if %%I == %Month% goto :EOF
for %%I in (4 6 9 11) do if %%I == %Month% if %Day% == 31 (goto InvalidDate) else goto :EOF
set /A LeapYear=Year %% 4
rem Year range is 2000 to 2099 for which one leap year rule is enough.
if %LeapYear% == 0 (set "LastDayInFeb=29") else set "LastDayInFeb=28"
if %Day% LEQ %LastDayInFeb% goto :EOF

:InvalidDate
echo %Value% is not a validate for %~2.
goto GetValue

:CreateFiles
rem Last day in month for standard years.
set "Month_S_1=31"
set "Month_S_2=28"
set "Month_S_3=31"
set "Month_S_4=30"
set "Month_S_5=31"
set "Month_S_6=30"
set "Month_S_7=31"
set "Month_S_8=31"
set "Month_S_9=30"
set "Month_S_10=31"
set "Month_S_11=30"
set "Month_S_12=31"

rem Last day in month for leap years.
set "Month_L_1=31"
set "Month_L_2=29"
set "Month_L_3=31"
set "Month_L_4=30"
set "Month_L_5=31"
set "Month_L_6=30"
set "Month_L_7=31"
set "Month_L_8=31"
set "Month_L_9=30"
set "Month_L_10=31"
set "Month_L_11=30"
set "Month_L_12=31"

rem Split up initial date into year, month and day.
set "Year=%InitialDate:~0,4%"
set /A Month=1%InitialDate:~4,2% - 100
set /A Day=1%InitialDate:~6,2% - 100
set /A LeapYear=Year %% 4
if %LeapYear% == 0 (set "LeapYear=L") else set "LeapYear=S"
set "NextDate=%InitialDate%"

:NextFile
type NUL >"2v%UnitCode%%NextDate%.rep"
if %NextDate% == %FinalDate% goto EndBatch

rem Determine first last day in current month of current year.
setlocal EnableDelayedExpansion
set "LastDayInMonth=!Month_%LeapYear%_%Month%!"
endlocal & set "LastDayInMonth=%LastDayInMonth%"

rem Increment the date by one day.
set /A Day+=1
if %Day% LEQ %LastDayInMonth% goto BuildDate
set "Day=1"
set /A Month+=1
if %Month% LEQ 12 goto BuildDate
set "Month=1"
set /A Year+=1
set /A LeapYear=Year %% 4
if %LeapYear% == 0 (set "LeapYear=L") else set "LeapYear=S"

:BuildDate
set "TwoDigitMonth=0%Month%"
set "TwoDigitMonth=%TwoDigitMonth:~-2%"
set "TwoDigitDay=0%Day%"
set "TwoDigitDay=%TwoDigitDay:~-2%"
set "NextDate=%Year%%TwoDigitMonth%%TwoDigitDay%"
goto NextFile

:EndBatch
endlocal

It would be much better to use PowerShell for this task. PowerShell supports built-in string validation using a regular expression and also supports natively handling of dates with date calculations which the Windows command processor CMD does not support at all.

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.

  • call /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • type /?

See also:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM