I am working on a program, and all of the parts work perfectly except one, that part is supposed to generate a seven digit random number which is divisible by 7.
I am aware that there are similiar questions to mine, but I did not find my anwser within them, and despite trying I was myself only capable of somethimes generating such a number.
Any idea how to do so?
You can use the modulo function (see set /?):
#echo off
setlocal
set "number=%random%%random%%random%%random%%random%%random%%random%"
set "number=%number:~0,7%"
set /a remainder=number %% 7
if %remainder% equ 0 (
echo %number% is a multiple of 7
) else (
echo %number% divided by 7 gives a rest of %remainder%
)
Just in case, leading zero(s) is/are ok or even desired as a possibility:
#echo off
setlocal
set "number=%random%%random%%random%%random%%random%%random%%random%"
set "number=%number:~-7%"
set /a remainder=7%number% %% 7
if %remainder% equ 0 (
echo %number% is a multiple of 7
) else (
echo %number% divided by 7 gives a rest of %remainder%
)
Here's a slightly different method, which is designed to propagate a variable, named D7 with a seven digit value, which when divided by seven will return an exact integer:
This first example allows for leading 0's in the resulting value.
Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "D7="
For /L %%G In (0 1 9) Do For %%H In (
%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%
) Do (Set /A D7 = 7%%H%%G %% 7
SetLocal EnableDelayedExpansion & If !D7! Equ 0 (EndLocal
Set "D7=%%H%%G"
GoTo :Next))
:Next
Set D7
Pause
Please note: It is possible that the resulting value could be 0000000 because leading 0's are allowed and 0 is divisible by every integer.
If you do not want to have leading 0's then a very small adaptation is needed:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "D7="
For /L %%G In (1 1 9) Do For %%H In (
%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%
) Do (Set /A D7 = %%G%%H %% 7
SetLocal EnableDelayedExpansion & If !D7! Equ 0 (EndLocal
Set "D7=%%G%%H"
GoTo :Next))
:Next
Set D7
Pause
This question already has an answer here:
Split a CSV file into multiple files with header and given number of records
(1 answer)
Closed 1 year ago.
I have a text file. The first line is header. rest of the lines are data. It may contain thousand lines of data. I need to write a batch script which will split the master files into many files each of them contains maximum 500 lines of data and the same header as master file.
Master file
heder
1
2
3
4
.
.
.
.
1501
it will split the file into 4 files. The fourth one will have the header and 1501
You can get a total count of lines in a file using find and calculate the number of files needed by using a for /l loop on the count of the lines in steps of 500
the below approach examples such - in this way files are created with the header and lines output in accordance with the 500 per file using a paired GTR LEQ conditional test.
#Echo off & CD /D "%~dp0"
:# Primary environment has Delayed Expansion Disabled until after assignment of input
:# to retain '!' characters.
Setlocal EnableExtensions DisableDelayedExpansion
Set "line[i]="
Set "files="
:# Get a count of total lines and how many files to make per 500
for /f %%a in ('type "infile.txt"^|find "" /v /c') do Set /A TTL=%%a-1
For /l %%i in (0 500 %TTL%)Do Set /A files+=1
Set /P "Header=" <"infile.txt"
:# Delayed expansion provides protection against poison characters
Setlocal EnableDelayedExpansion
:# Create or Overide each outfile using the assigned input from set /p
For /l %%i in (1 1 %files%)Do >"Outfile%%i.txt" Echo(!Header!
Endlocal
:# Outer for /f loop skips header line; counts each line in.
:# Inner for /l loop iterates over group size with assigned offset 'Stop'
:# Dual GTR LEQ conditional test of Lne[i] used to output in desired group
For /f "Skip=1 Delims=" %%G in (infile.txt)Do (
Set /A "Line[i]+=1"
Set "Line=%%G"
Setlocal EnableDelayedExpansion
Set "file[i]=0"
For /l %%i in (0 500 !TTL!)Do (
Set /A "Stop=%%i+500"
Set /A "file[i]+=1"
If !Line[i]! GTR %%i If !Line[i]! LEQ !Stop! (
Title File: !file[i]! / !files! Line: !Line[i]! / !TTL!
>>"Outfile!file[i]!.txt" Echo(!Line!
)
)
Endlocal
)
Here you go:
#echo off
setlocal EnableDelayedExpansion
set /a maxNoOfLinesPerFile = 500
set /a lineCount = 0
set /a fileCount = 0
set header=""
set outFileNamePrefix=outFile
for /F "tokens=*" %%A in (source.txt) do (
if !lineCount!==0 (
set header=%%A
) else (
set /a n = !lineCount! %% !maxNoOfLinesPerFile!
REM echo !n!
if !n!==1 (
set /a fileCount = fileCount + 1
set outFileName=!outFileNamePrefix!_!fileCount!.txt
echo !outFileName!
echo !header! >> !outFileName!
echo %%A >> !outFileName!
) else (
echo %%A >> !outFileName!
)
)
set /a lineCount = lineCount + 1
)
I'm trying to compare a sequence of 9 numbers (separated by ,) using a batch file.
The comparison is always made by the corresponding sequence like:
mPrevious[0] <-> mCurrent[0]
mPrevious[1] <-> mCurrent[1]
I need to know if at least one sequece have changed. In the example bellow, 234 changed to 230 and 146 to 149.
The sketch I have so far is:
setlocal ENABLEDELAYEDEXPANSION
#echo off
set mPrevious=229,234,235,127,58,0,131,133,146
set mCurrent=229,230,235,127,58,0,131,133,149
for /f "tokens=1,2,3,4,5,6,7,8,9 delims=," %%a IN ('echo !mPrevious!') do (
)
The number of entries (currently 9) might change in the future. But for now they are just 9.
I'm not sure what is the proper way to do it inside a batch script.
#echo off
title <nul && title ...\%~nx0
setlocal enabledelayedexpansion
set "_mPrevious=229,234,235,127,58,0,131,133,146"
set "_mCurrents=229,230,235,127,58,0,131,133,149"
echo/!_mPrevious!|find "!_mCurrents!" >nul && (
endlocal & echo\Nothing changed^!! & goto :EOF )
for %%i in (!_mPrevious!)do set /a "_i+=1+0" && call set "_mPrev_!_i!=%%~i"
for %%j in (!_mCurrents!)do set /a "_j+=1+0" && call set "_mCurr_!_j!=%%~j"
if !_i! neq !_j! endlocal & echo\Varyables have different lengths^!! & goto :EOF
for /L %%L in (1 1 !_j!)do if !_mPrev_%%~L! neq !_mCurr_%%~L! echo\!_mPrev_%%~L! updated to: !_mCurr_%%~L!
endlocal && goto :EOF
Outputs:
234 updated to: 230
146 updated to: 149
One simple way to do this only if necessary and only if both variable has same length:
Make a first comparison if the variables are the same, there was a change in the values:
echo/!_mPrevious!|find "!_mCurrents!" >nul && (
endlocal & echo\Nothing changed^!! & goto :EOF )
And a second if they continue with the same length:
if !_i! neq !_j! endlocal & echo\Variables have different lengths^!! & goto :EOF
Obs.: 1. I prefer replace [ ] to one simple _
Obs.: 2. Also, change i+= to _i+=1+0, where no need predefined set command: set i=0
The FOR token delimiters are: <SPACE> <TAB> <NBSP> , ; =
Therefore, you can put it into a FOR loop, but it would fail if the content contained * or ?.
#echo off
====SETLOCAL EnableDelayedExpansion EnableExtensions
set/a"#=cnt=0"
::Define lists
set "mPrevious=229,234,235,127,58,0,131,133,146"
set "mCurrent=229,230,235,127,58,0,131,133,149"
FOR %%P in (!mPrevious!) do (
FOR %%C in (!mCurrent!) do (
if !cnt! equ !#! echo(%%P %%C
set/a"cnt+=1"
)
set/a"cnt=0,#+=1"
)
This is an approach using some self-expanding code:
#echo off
setlocal EnableDelayedExpansion
rem // Define constants here:
set "mPrevious=229,234,235,127,58,0,131,133,146"
set "mCurrents=229,230,235,127,58,0,131,133,149"
rem // Initialise auxiliary variables and indexes:
set "nPrevious=,%mPrevious%" & set /A "i=0"
set "nCurrents=,%mCurrents%" & set /A "j=0"
rem // Convert lists to arrays using self-expanding code:
set "_=%nPrevious:,=" & set /A "i+=1" & set "nPrevious[!i!]=%"
set "_=%nCurrents:,=" & set /A "j+=1" & set "nCurrents[!j!]=%"
rem // Verify availability of arrays:
> nul 2>&1 set nPrevious[ || set /A "i=0"
> nul 2>&1 set nCurrents[ || set /A "j=0"
rem // Determine minimal and maximal count:
if %j% gtr %i% (set /A "k=i, l=j" & set "_=#") else (set /A "k=j, l=i" & set "_=")
rem // Compare corresponding elements:
for /L %%K in (1,1,%k%) do if !nPrevious[%%K]! neq !nCurrents[%%K]! (
echo [%%K]: !nPrevious[%%K]! -^> !nCurrents[%%K]!
)
rem // Return removed or added elements:
set /A "k+=1" & for /L %%K in (!k!,1,%l%) do if defined _ (
echo [%%K]: --- -^> !nCurrents[%%K]!
) else (
echo [%%K]: !nPrevious[%%K]! -^> ---
)
endlocal
Sample output, relying on the data of the question:
[2]: 234 -> 230
[9]: 146 -> 149
I don't understand why this script doesn't seem to work and doesn't even pause to see where the error is.. Here is the code for the batch file:
I want this batch to output a series of birthdays starting from Ihf0101 till Ihf3112
set /a month=1
:m
if %month% leq 12
(
set /a day=1
:d
if %day% leq 31
(
if %day% leq 9 set birthday=Ihf0%day%
if %day% gtr 9 set birthday=Ihf%day%
if %month% leq 9
(
set birthday=%birthday%0%month%
echo %birthday%
)
if %month% gtr 9
(
set birthday=%birthday%%month%
echo %birthday%
)
set /a day+=1
goto :d
)
set /a month+=1
goto :m
)
pause
Use for /L loops instead:
#echo off
setlocal enabledelayedexpansion
set "y=2017"
for /l %%m in (101,1,112) do (
set "m=%%m"
for /l %%d in (101,1,131) do (
set "d=%%d"
xcopy /d:!m:~1!-!d:~1!-%y% /l . .. >nul 2>&1 && echo lhf!d:~1!!m:~1!
)
)
two little tricks:
- counting from 101 to 131 and taking the last two digits only gives you a two-digit format always (with leading zero for numbers below 10)
- using xcopy to check if the date is really existent (I learned that here) (necessary to know the year for proper calculation of leap-years)
So I have a text file that I read which contains multiple lines of words. For now it contains "Successful" and failed.
Here's my code.
setlocal enabledelayedexpansion
for /l %%x in (1, 1, 50) do (
for /f "tokens=*" %%a in (D:\Errors.txt) do echo %%x %%a >>D:\list.txt
)
Basically what I want to output are the words in Errors.txt at random which is mapped from 1 - 50.
Currently this is the output of my code and it's not at random. Also the numbering repeats which I guess is expected due to the loop. Any help would greatly be appreciated. Thanks!
1 Successful
1 Failed
2 Successful
2 Failed
3 Successful
3 Failed
4 Successful
4 Failed
5 Successful
5 Failed
6 Successful
6 Failed
7 Successful
7 Failed
Basically end goal should be like this. Successful/Failed are applied at random while the numbers 1 - 50 are consistent.
1 Successful
2 Failed
3 Failed
4 Successful
5 Successful
6 Successful
7 Failed
This method works with any number of lines in the Errors.txt file:
#echo off
setlocal EnableDelayedExpansion
(
rem Load the lines from the file
set n=0
for /F "delims=" %%a in (D:\Errors.txt) do (
set "line[!n!]=%%a"
set /A n+=1
echo !n! %%a
)
rem Repeat same lines the rest of times in random order
set /A nP1=n+1
for /L %%i in (!nP1!,1,50) do (
set /A i=!random! %% n
call echo %%i %%line[!i!]%%
)
) > D:\list.txt
#echo off
setlocal EnableDelayedExpansion
set n=0
(
REM read from file
for /f "tokens=*" %%a in (D:\Errors.txt) do (
set /a n+=1
echo !n! %%a
)
REM for the rest until 50:
for /l %%a in (!n!,1,49) do (
set /a n+=1
set /a x=!random! %% 2
if !x!==0 (
echo !n! successful
) else (
echo !n! failed
)
)
)>D:\list.txt
type D:\list.txt