The following batch file works perfectly for the first 10 options. However I do not know how to extend the functionality of the batch file more than 10 option 0- 9. I have 35 possible options.
#ECHO OFF
MODE CON:COLS=100 LINES=50
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
(SET sourceFolder=C:\Users\Administrator\Desktop\test)
](SET targetFolder=C:\Users\Administrator\Desktop\test2)
SET /P "customerID=Enter Customer ID: "
:MENU
CLS
ECHO=
ECHO= ..................................................
ECHO= PLEASE SELECT THE OPTION FROM THE EVENT MENU BELOW
ECHO= ..................................................
ECHO Option Number Event Number Event Name
ECHO.
ECHO. 0. 101 NewCustomer
ECHO. 1. 102 ExisingCustomer
ECHO. 2. 103 LockedAccount
ECHO. 3. 104 DeleteAccount
ECHO. 4. 105 ExpireSession
ECHO. 5. 106 PasswordUpdated
ECHO. 6. 107 PasswordReset
ECHO. 7 108 HackedAccount
ECHO. 8. 109 UpdateProfile
ECHO. 9. 110 UpdateLists
ECHO. A. 111 NewPurchase
ECHO. B. 112 ExisingSale
ECHO. C. 113 AmendOrder
ECHO. D. 114 AmendDelivery
ECHO. E. 115 CancelOrder
ECHO. F. 116 OvernightFiles
ECHO. G. 117 DailyFiles
ECHO. H. 118 HelpFlies
ECHO. I. 119 FraudAccount
ECHO. J. 120 DeadCustomer
ECHO. K. 121 WelcomeEmail
ECHO. L. 122 OrderEmail
ECHO. M. 123 OrderAmmended
ECHO. N. 124 NoRemainingStock
ECHO. O. 125 ReplenishStock
ECHO. P. 126 SalesQuery
ECHO. Q. 127 UpdateFirstName
ECHO. R. 128 UpdateSurname
ECHO. S. 129 UpdateAddress
ECHO. T. 130 UpdateDateOfBirth
ECHO. U. 131 UpdateContactNo
ECHO. V. 132 UpdateEmail
ECHO. W. 133 UpdatePreferences
ECHO. X. 134 UpdateEmailPreferences
ECHO. Y. 135 UpdateBankDetails
CHOICE /C 0123456789ABCDEFGHIJKLMNOPQRSTUVWXY /M "CHOOSE AN OPTION"
SET "Option=%ERRORLEVEL%"
FOR /F "TOKENS=1-4 DELIMS=. " %%A IN ('FINDSTR/BC:"ECHO. " "%~f0"'
) DO IF "%%B"=="%Option%" (SET "Name=%%C" & SET "Code=%%D")
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MISC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%Name%"'
) DO COPY "%%A" "%targetFolder%"
PAUSE
Took me some time to understand what your problem was:
when you type a choice, you get the index of the choice and not the relevant letter, making it impossible to link back to the selected item of the menu if not 0-9.
So I propose to convert back your index to the entered letter like this (extract):
SET "Option=%ERRORLEVEL%" <== this is your code
rem here scan for correct letter
FOR /L %%a IN (0,1,35) DO if %%a==%Option% set idx=%%a
rem small correction of index
set /A idx-=1
set Option=!Choice:~%idx%,1!
Full test code, pressing a digit or a letter prints the letter and the code & title of the menu:
#echo off
set CHOICE=0123456789ABCDEFGHIJKLMNOPQRSTUVWXY
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
:MENU
CLS
ECHO=
ECHO= ..................................................
ECHO= PLEASE SELECT THE OPTION FROM THE EVENT MENU BELOW
ECHO= ..................................................
ECHO Option Number Event Number Event Name
ECHO.
ECHO. 0. 101 NewCustomer
ECHO. 1. 102 ExisingCustomer
ECHO. 2. 103 LockedAccount
ECHO. 3. 104 DeleteAccount
ECHO. 4. 105 ExpireSession
ECHO. 5. 106 PasswordUpdated
ECHO. 6. 107 PasswordReset
ECHO. 7 108 HackedAccount
ECHO. 8. 109 UpdateProfile
ECHO. 9. 110 UpdateLists
ECHO. A. 111 NewPurchase
ECHO. B. 112 ExisingSale
ECHO. C. 113 AmendOrder
ECHO. D. 114 AmendDelivery
ECHO. E. 115 CancelOrder
ECHO. F. 116 OvernightFiles
ECHO. G. 117 DailyFiles
ECHO. H. 118 HelpFlies
ECHO. I. 119 FraudAccount
ECHO. J. 120 DeadCustomer
ECHO. K. 121 WelcomeEmail
ECHO. L. 122 OrderEmail
ECHO. M. 123 OrderAmmended
ECHO. N. 124 NoRemainingStock
ECHO. O. 125 ReplenishStock
ECHO. P. 126 SalesQuery
ECHO. Q. 127 UpdateFirstName
ECHO. R. 128 UpdateSurname
ECHO. S. 129 UpdateAddress
ECHO. T. 130 UpdateDateOfBirth
ECHO. U. 131 UpdateContactNo
ECHO. V. 132 UpdateEmail
ECHO. W. 133 UpdatePreferences
ECHO. X. 134 UpdateEmailPreferences
ECHO. Y. 135 UpdateBankDetails
CHOICE /C %CHOICE% /M "CHOOSE AN OPTION"
SET "Option=%ERRORLEVEL%"
rem here scan for correct letter
FOR /L %%a IN (0,1,35) DO if %%a==%Option% set idx=%%a
rem small correction of index
set /A idx-=1
set Option=!Choice:~%idx%,1!
FOR /F "TOKENS=1-4 DELIMS=. " %%A IN ('FINDSTR/BC:"ECHO. " "%~f0"'
) DO (IF "%%B"=="%Option%" (SET "Name=%%C" & SET "Code=%%D" & echo activated %Option%: !Name!,!Code!)
)
Notes:
I needed to enable delayed expansion back
I set CHOICE in a variable at the start, nicer to propose the choice and then scan into it for correct letter/digit
May I suggest a different approach based on arrays that run faster and is simpler to keep updated?
#ECHO OFF
MODE CON:COLS=100 LINES=50
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
(SET sourceFolder=C:\Users\Administrator\Desktop\test)
(SET targetFolder=C:\Users\Administrator\Desktop\test2)
SET /P "customerID=Enter Customer ID: "
REM Assemble the data arrays
set i=0
set "options="
FOR /F "TOKENS=1-4 DELIMS=. " %%A IN ('FINDSTR/BC:"ECHO. " "%~f0"') DO (
set /A i+=1
set "options=!options!%%B"
SET "Name[!i!]=%%C"
SET "Code[!i!]=%%D"
)
:MENU
CLS
ECHO=
ECHO= ..................................................
ECHO= PLEASE SELECT THE OPTION FROM THE EVENT MENU BELOW
ECHO= ..................................................
ECHO Option Number Event Number Event Name
ECHO/
ECHO. 0. 101 NewCustomer
ECHO. 1. 102 ExisingCustomer
ECHO. 2. 103 LockedAccount
ECHO. 3. 104 DeleteAccount
ECHO. 4. 105 ExpireSession
ECHO. 5. 106 PasswordUpdated
ECHO. 6. 107 PasswordReset
ECHO. 7 108 HackedAccount
ECHO. 8. 109 UpdateProfile
ECHO. 9. 110 UpdateLists
ECHO. A. 111 NewPurchase
ECHO. B. 112 ExisingSale
ECHO. C. 113 AmendOrder
ECHO. D. 114 AmendDelivery
ECHO. E. 115 CancelOrder
ECHO. F. 116 OvernightFiles
ECHO. G. 117 DailyFiles
ECHO. H. 118 HelpFlies
ECHO. I. 119 FraudAccount
ECHO. J. 120 DeadCustomer
ECHO. K. 121 WelcomeEmail
ECHO. L. 122 OrderEmail
ECHO. M. 123 OrderAmmended
ECHO. N. 124 NoRemainingStock
ECHO. O. 125 ReplenishStock
ECHO. P. 126 SalesQuery
ECHO. Q. 127 UpdateFirstName
ECHO. R. 128 UpdateSurname
ECHO. S. 129 UpdateAddress
ECHO. T. 130 UpdateDateOfBirth
ECHO. U. 131 UpdateContactNo
ECHO. V. 132 UpdateEmail
ECHO. W. 133 UpdatePreferences
ECHO. X. 134 UpdateEmailPreferences
ECHO. Y. 135 UpdateBankDetails
CHOICE /C %options% /M "CHOOSE AN OPTION"
SET "Option=%ERRORLEVEL%"
SET "Name=!Name[%Option%]!" & SET "Code=!Code[%Option%]!"
FOR /F "DELIMS=" %%A IN (
'FINDSTR/MISC:"%customerID%" "%sourceFolder%\*"^|FINDSTR/MIF:/ /C:"%Name%"'
) DO COPY "%%A" "%targetFolder%"
PAUSE
As an alternative:
#ECHO OFF
MODE CON:COLS=50 LINES=50
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
(SET sourceFolder=C:\test)
(SET targetFolder=C:\test2)
SET /P "customerID=Enter Customer ID: "
:MENU
"SET _="
CLS
ECHO=
ECHO= ................................................
ECHO= PLEASE SELECT THE EVENT CODE FROM THE MENU BELOW
ECHO= ................................................
ECHO=
ECHO= Event Code -=- Event Name
ECHO=
ECHO. 101 --- NewCustomer
ECHO. 102 --- ExisingCustomer
ECHO. 103 --- LockedAccount
ECHO. 104 --- DeleteAccount
ECHO. 105 --- ExpireSession
ECHO. 106 --- PasswordUpdated
ECHO. 107 --- PasswordReset
ECHO. 108 --- HackedAccount
ECHO. 109 --- UpdateProfile
ECHO. 110 --- UpdateLists
ECHO. 111 --- NewPurchase
ECHO. 112 --- ExisingSale
ECHO. 113 --- AmendOrder
ECHO. 114 --- AmendDelivery
ECHO. 115 --- CancelOrder
ECHO. 116 --- OvernightFiles
ECHO. 117 --- DailyFiles
ECHO. 118 --- HelpFlies
ECHO. 119 --- FraudAccount
ECHO. 120 --- DeadCustomer
ECHO. 121 --- WelcomeEmail
ECHO. 122 --- OrderEmail
ECHO. 123 --- OrderAmmended
ECHO. 124 --- NoRemainingStock
ECHO. 125 --- ReplenishStock
ECHO. 126 --- SalesQuery
ECHO. 127 --- UpdateFirstName
ECHO. 128 --- UpdateSurname
ECHO. 129 --- UpdateAddress
ECHO. 130 --- UpdateDateOfBirth
ECHO. 131 --- UpdateContactNo
ECHO. 132 --- UpdateEmail
ECHO. 133 --- UpdatePreferences
ECHO. 134 --- UpdateEmailPreferences
ECHO. 135 --- UpdateBankDetails
ECHO=
SET/P "PICK= > "
FOR /F "EOL=F TOKENS=2-3 DELIMS=.- " %%A IN ('FIND " --- " "%~f0"') DO (
IF %PICK%==%%A (SET "_=T"
FOR /F "DELIMS=" %%C IN (
'FINDSTR/MISC:"%customerID%" "%sourceFolder%\*"
^|FINDSTR/MIF:/ /C:"%%B"') DO COPY "%%C" "%targetFolder%"))
IF NOT DEFINED _ GOTO :MENU
TIMEOUT -1
Related
I've pieced together a batch file based on info I've found here. Oddly, an earlier version appeared to work correctly at home, once I took it to work, it didn't. And all my modifications are failing to fix it. My boss and I are stuck.
#echo off
setlocal
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:"IPv4 Address"`) do (
for /f "tokens=1-4 delims=. " %%a in ("%%f") do (
set octetA=%%a set octetB=%%b set octetC=%%c set octetD=%%d
if %octetB% equ 10 goto :setschool
)
)
:setschool
if %octetC% geq 0 if %octetC% leq 3 set school=DIC
if %octetC% geq 16 if %octetC% leq 19 set school=AT
if %octetC% geq 48 if %octetC% leq 51 set school=BE
if %octetC% geq 64 if %octetC% leq 67 set school=BH
if %octetC% geq 80 if %octetC% leq 83 set school=CN
if %octetC% geq 112 if %octetC% leq 115 set school=LC
if %octetC% geq 128 if %octetC% leq 131 set school=LX
if %octetC% geq 144 if %octetC% leq 147 set school=RG
if %octetC% geq 160 if %octetC% leq 163 set school=UN
if %octetC% geq 176 if %octetC% leq 179 set school=WA
if %octetC% geq 192 if %octetC% leq 195 set school=WI
if %octetC% geq 208 if %octetC% leq 211 set school=BOE
echo %school%
goto :eof
It errors out at the first 'if', because octetB hasn't been set to anything yet. Yet the code just before it should have set it. All of our wired DHCP addresses start with 10.10., which is why it's checking for 10, which should mean it ignores our wireless, auto configed IPs, and virtual nics. If I manually run the lines before the 'if', it produces what I expect, with the octets being set correctly.
I suspect that the output of ipconfig is different at home and at work. Do you run the same operating systems on them? With the same language setting? Do the ipconfig outputs on both machines contain a IPv4 Address line when checked manually?
But I cannot tell anything without knowing the "earlier version that worked" you mentioned.
You can try using a simpler search String that is common on both machines, like IPv4. And maybe you want to add the /I switch to the findStr call to set it to "ignore case".
Try checking for equality with if "%%b" == "10" goto setschool (remove the colon, replace %octetB%). I think %octetB% is only available inside the for loop if you work with delayed expansion of variables.
You need to put each set command on its own line inside the for loop.
With these changes it works for me at least under Win10.
This is how I find which IP subnet our machines are using:
ipconfig^|findstr /i /c:"ip address"^|findstr /c:"10.11.1"&&set loc=AAA&&goto :continue
ipconfig^|findstr /i /c:"ipv4 address"^|findstr /c:"10.11.1"&&set loc=AAA&&goto ipconfig^|findstr /i /c:"ip address"^|findstr /c:"192.168.4."&&set loc=BBB&&goto :continue
:continue
ipconfig^|findstr /i /c:"ipv4 address"^|findstr /c:"192.168.4."&&set loc=BBB&&goto :continue
set loc=unknown
:continue
I think "ip address" is from WinXP or Win7.
You need delayed expansion.
untested
#echo off
setlocal enabledelayedexpansion
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:"IPv4 Address"`) do (
for /f "tokens=1-4 delims=. " %%a in ("%%f") do (
set octetA=%%a & set octetB=%%b & set octetC=%%c & set octetD=%%d
if "!octetB!" equ "10" goto :setschool
)
)
Here's a Remarked batch file example, showing the fix for your issues, as per my initial comment:
#Echo Off
Rem Undefine any existing octet variables.
For /F "Delims==" %%G In ('Set octet 2^>NUL') Do Set "%%G="
Rem Retrieve the IPv4 string from the IPConfig command.
Rem And set each octet to individual variables.
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL | %__Appdir__%find.exe "IPv4""'
) Do For /F "Tokens=1-4 Delims=. " %%H In ("%%G"
) Do Set "octet1=%%H" & Set "octet2=%%I" & Set "octet3=%%J" & Set "octet4=%%K"
Rem Check to see if any octet variables are defined, i.e. IPv4 found.
Rem If not print message, wait for response and end the script.
Set octet >NUL 2>&1 || (Echo IPConfig failed to retrieve an IP address.
Pause & GoTo :EOF)
Rem From here you can make your comparisons:
Rem First ensure that a variable named school is not defined.
Set "school="
Rem Check to see if your second octet was 10.
Rem Then make your comparisons using the value of the third octet.
If %octet2% Equ 10 If Defined octet3 (
If %octet3% GEq 0 If %octet3% LEq 3 Set "school=DIC"
If %octet3% GEq 16 If %octet3% LEq 19 Set "school=AT"
If %octet3% GEq 48 If %octet3% LEq 51 Set "school=BE"
If %octet3% GEq 64 If %octet3% LEq 67 Set "school=BH"
If %octet3% GEq 80 If %octet3% LEq 83 Set "school=CN"
If %octet3% GEq 112 If %octet3% LEq 115 Set "school=LC"
If %octet3% GEq 128 If %octet3% LEq 131 Set "school=LX"
If %octet3% GEq 144 If %octet3% LEq 147 Set "school=RG"
If %octet3% GEq 160 If %octet3% LEq 163 Set "school=UN"
If %octet3% GEq 176 If %octet3% LEq 179 Set "school=WA"
If %octet3% GEq 192 If %octet3% LEq 195 Set "school=WI"
If %octet3% GEq 208 If %octet3% LEq 211 Set "school=BOE")
Rem As your comparisons do not currently cover all possible octet values,
Rem This is a check to see if the school variable was actually defined.
Rem If not print message, otherwise print the content of the school variable.
If Not Defined school (Echo The school variable was not defined.
Echo Reason: & If %octet2% Neq 10 (Echo The second octet was not 10.
) Else If Defined octet3 (Echo The third octet failed the comparisons.
) Else Echo Your returned IP address was corrupted.) Else Echo %school%
Rem Wait to ensure that any messages can be read, if not run from cmd.exe.
Pause
Rem End script.
GoTO :EOF
The script includes some additions designed to provide reasonable feedback if errors occur.
Feel free to use this unRemarked version for completion or in your production environment.
#Echo Off
For /F "Delims==" %%G In ('Set octet 2^>NUL')Do Set "%%G="
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL|%__Appdir__%find.exe "IPv4""'
)Do For /F "Tokens=1-4Delims=. " %%H In ("%%G"
)Do Set "octet1=%%H"&Set "octet2=%%I"&Set "octet3=%%J"&Set "octet4=%%K"
Set octet>NUL 2>&1||(Echo IPConfig failed to retrieve an IP address.
Pause&GoTo :EOF)
Set "school="
If %octet2% Equ 10 If Defined octet3 (
If %octet3% GEq 0 If %octet3% LEq 3 Set "school=DIC"
If %octet3% GEq 16 If %octet3% LEq 19 Set "school=AT"
If %octet3% GEq 48 If %octet3% LEq 51 Set "school=BE"
If %octet3% GEq 64 If %octet3% LEq 67 Set "school=BH"
If %octet3% GEq 80 If %octet3% LEq 83 Set "school=CN"
If %octet3% GEq 112 If %octet3% LEq 115 Set "school=LC"
If %octet3% GEq 128 If %octet3% LEq 131 Set "school=LX"
If %octet3% GEq 144 If %octet3% LEq 147 Set "school=RG"
If %octet3% GEq 160 If %octet3% LEq 163 Set "school=UN"
If %octet3% GEq 176 If %octet3% LEq 179 Set "school=WA"
If %octet3% GEq 192 If %octet3% LEq 195 Set "school=WI"
If %octet3% GEq 208 If %octet3% LEq 211 Set "school=BOE")
If Not Defined school (Echo The school variable was not defined.
Echo Reason:&If %octet2% Neq 10 (Echo The second octet was not 10.
)Else If Defined octet3 (Echo The third octet failed the comparisons.
)Else Echo Your returned IP address was corrupted.)Else Echo %school%
Pause
GoTO :EOF
is there a way to make a If query for specifig
number sections in Batch?
Something Like this:
IF "Var1"=="1-10" (
do something
)
the 1-10 should stand for 1,2,3,4,5,6,7,8,9,10.
I want to make 10 queries (1-10,11-20,21-30, ... , 91-100)
Is that possible?
You can do this:
#echo off
set Var1=1
for /l %%i in (0,1,10) do if %%i==%Var1% echo 10 or below
for /l %%i in (11,1,20) do if %%i==%Var1% echo 11 - 20
for /l %%i in (21,1,30) do if %%i==%Var1% echo 21 - 30
for /l %%i in (31,1,40) do if %%i==%Var1% echo 31 - 40
for /l %%i in (41,1,50) do if %%i==%Var1% echo 41 - 50
for /l %%i in (51,1,60) do if %%i==%Var1% echo 51 - 60
for /l %%i in (61,1,70) do if %%i==%Var1% echo 61 - 70
for /l %%i in (71,1,80) do if %%i==%Var1% echo 71 - 80
for /l %%i in (81,1,90) do if %%i==%Var1% echo 81 - 90
for /l %%i in (91,1,100) do if %%i==%Var1% echo 91 - 100
Here you can change set Var1=1 to any other number and it will correspond. You can replace echo N - N with your commands.
Also, set Var1=1 can be removed from the above example if used with your code as I simply set it to demonstrate the behaviour. Here is an extract from the help when running for /? so you understand the numeric behaviour.
FOR /L %variable IN (start,step,end) DO command [command-parameters]
The set is a sequence of numbers from start to end, by step amount.
So (1,1,5) would generate the sequence 1 2 3 4 5 and (5,-1,1) would
generate the sequence (5 4 3 2 1)
I have a text file with N number of rows and columns, whereas I need to get particular columns with their values and load it into a new text file using batch script, e.g.:
input.txt
col1|col2|col3.....col71|col72
ew|ds|343.....csdk|gfdf
xc|gh|657.....sdfs|utyy
qw|zx|345.....ffds|xzcz
output.txt
col71|col3
csdk|343
sdfs|657
ffds|345
To split text into tokens by (a) certain delimiter(s), use the for /F loop. However, this can only handle up to 31 tokens, so you cannot simply state tokens=71, but you can nest multiple loops:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
> "output.txt" (
rem // Split off the first 31 tokens, pass the rest to the next loop:
for /F "usebackq delims=| eol=| tokens=3,31*" %%A in ("input.txt") do (
rem // Split off the next 31 tokens, pass the rest to the next loop:
for /F "delims=| eol=| tokens=31*" %%D in ("%%C") do (
rem /* Extract the proper token from the remaining ones (remember
rem that 31 + 31 = 62 tokens have been split off before): */
for /F "delims=| eol=| tokens=9" %%F in ("%%E") do (
echo(%%F^|%%A
)
)
)
)
endlocal
If there may be empty columns, the above approach fails, because for /F treats consecutive delimiters as one. To overcome this, you could do the following:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
> "output.txt" (
rem // Read complete lines:
for /F usebackq^ delims^=^ eol^= %%L in ("input.txt") do (
rem // Store current line string in interim variable:
set "LINE=%%L"
setlocal EnableDelayedExpansion
rem /* Split off the first 31 tokens, pass the rest to the next loop;
rem to avoid consecutive delimiters `|`, replace every single one by
rem :`"|"`, so `||` becomes `"|""|"`; then enclose the entire result
rem within `""`, thus achieving individual tokens enclosed within `""`: */
for /F "delims=| tokens=3,31*" %%A in (^""!LINE:|="^|"!"^") do (
endlocal
rem // Split off the next 31 tokens, pass the rest to the next loop:
for /F "delims=| tokens=31*" %%D in ("%%C") do (
rem /* Extract the proper token from the remaining ones (remember
rem that 31 + 31 = 62 tokens have been split off before): */
for /F "delims=| tokens=9" %%F in ("%%E") do (
rem // Remove the previously added surrounding `""` by `~`:
echo(%%~F^|%%~A
)
)
setlocal EnableDelayedExpansion
)
endlocal
)
)
endlocal
This approach will still fail if there are already quoted field values that contain | on their own.
Linux
You could use awk -F "|" '{ print $70 "|" $2 }' input.txt > output.txt.
Usually one would probably execute cut -d"|" -f2,70 input.txt > output.txt, the only problem is that cut (as far as I know) doesn't support reordering columns.
Powershell
On Windows' powershell (also available for Linux) you can use the following snippet:
Get-Content 'input.txt' | ForEach-Object {
$array = $_.split("|")
$array[70] + '|' + $array[2]
} | Out-File 'output.txt'
The following Batch file is a general-purpose program that use a series of nested FOR /F commands that allows access to up to 177 tokens, but in a very simple way:
#echo off
setlocal EnableDelayedExpansion
rem Method to use up to 177 tokens in a FOR /F command in a simple way
rem Antonio Perez Ayala
rem Create an example file with lines with 180 tokens each
(for %%a in (A B C) do (
set "line="
for /L %%i in (1,1,180) do set "line=!line! %%a%%i"
echo !line!
)) > test.txt
set "line="
rem Load the string of tokens characters from FOR-FcharsCP850.txt file
chcp 850 > NUL
if exist FOR-FcharsCP850.txt goto readChars
echo Creating FOR-F characters file, please wait...
set "options=/d compress=off /d reserveperdatablocksize=26"
type nul > t.tmp
> FOR-FcharsCP850.txt (
set /P "=0" < NUL
rem Create 87 characters in 38..124 range for 3 FOR's with "tokens=1-28*"
set "i=0"
for /L %%i in (38,1,124) do (
set /A i+=1, mod=i%%29
if !mod! neq 0 (
call :genchr %%i
type %%i.chr
del %%i.chr
)
)
rem Create 95 characters for 3 FOR's with "tokens=1-31*"
rem This is the tokens sequence used when code page = 850
set "i=0"
for %%i in (173 189 156 207 190 221 245 249 184 166 174 170 240 169 238 248
241 253 252 239 230 244 250 247 251 167 175 172 171 243 168 183
181 182 199 142 143 146 128 212 144 210 211 222 214 215 216 209
165 227 224 226 229 153 158 157 235 233 234 154 237 232 225 133
160 131 198 132 134 145 135 138 130 136 137 141 161 140 139 208
164 149 162 147 228 148 246 155 151 163 150 129 236 231 152 ) do (
set /A i+=1, mod=i%%32
if !mod! neq 0 (
call :genchr %%i
type %%i.chr
del %%i.chr
)
))
del t.tmp temp.tmp
set "options="
:readChars
set /P "char=" < FOR-FcharsCP850.txt
set "lastToken=177"
cls
echo Enter tokens definition string in the same way of FOR /F "tokens=x,y,m-n" one
echo/
echo You may define a tokens range in descending order: "tokens=10-6" = 10 9 8 7 6
echo or add an increment different than 1: "tokens=10-35+5" = 10 15 20 25 30 35
echo Combine them: "tokens=10,28-32,170-161-3" = 10 28 29 30 31 32 170 167 164 161
echo/
echo The maximum token number is 177
:nextSet
echo/
set /P "tokens=tokens="
if errorlevel 1 goto :EOF
rem Expand the given tokens string into a series of individual FOR tokens values
set "tokensValues="
for %%t in (%tokens%) do (
for /F "tokens=1-3 delims=-+" %%i in ("%%t") do (
if "%%j" equ "" (
if %%i leq %lastToken% set "tokensValues=!tokensValues! %%!char:~%%i,1!"
) else (
if "%%k" equ "" (set "k=1") else set "k=%%k"
if %%i gtr %%j set "k=-!k!"
for /L %%n in (%%i,!k!,%%j) do if %%n leq %lastToken% set "tokensValues=!tokensValues! %%!char:~%%n,1!"
)
)
)
rem First three FOR's use as tokens the ASCII chars in 38..124 (&..|) range: 28*3 = 84 tokens + 3 tokens for next FOR
rem Next three FOR's use as tokens Extended chars: 31*3 = 93 tokens + 2 tokens for next FOR
rem based on the tokens sequence used when code page = 850
rem Total: 177 tokens
for /F "eol= tokens=1-28*" %%^& in (test.txt) do ^
for /F "eol= tokens=1-28*" %%C in ("%%B") do ^
for /F "eol= tokens=1-28*" %%` in ("%%_") do ^
for /F "eol= tokens=1-31*" %% in ("%%|") do ^
for /F "eol= tokens=1-31*" %%µ in ("%%·") do ^
for /F "eol= tokens=1-31" %% in ("%%…") do (
call :getTokens result=
rem Process here the "result" string:
echo !result!
)
goto nextSet
:getTokens result=
for %%# in (-) do set "%1=%tokensValues%"
exit /B
REM This code creates one single byte. Parameter: int
REM Teamwork of carlos, penpen, aGerman, dbenham
REM Tested under Win2000, XP, Win7, Win8
:genchr
if %~1 neq 26 (
makecab %options% /d reserveperfoldersize=%~1 t.tmp %~1.chr > nul
type %~1.chr | ( (for /l %%N in (1,1,38) do pause)>nul & findstr "^" > temp.tmp )
>nul copy /y temp.tmp /a %~1.chr /b
) else (
copy /y nul + nul /a 26.chr /a >nul
)
goto :eof
IMPORTANT: The series of six nested FOR /F commands use the following ASCII characters in the replaceable parameter and the character between quotes:
for /F "eol= tokens=1-28*" %%^& in (test.txt) do ^ %%^38
for /F "eol= tokens=1-28*" %%C in ("%%B") do ^ %%67 in ("66")
for /F "eol= tokens=1-28*" %%` in ("%%_") do ^ %%96 in ("95")
for /F "eol= tokens=1-31*" %% in ("%%|") do ^ %%173 in ("124")
for /F "eol= tokens=1-31*" %%µ in ("%%·") do ^ %%181 in ("183")
for /F "eol= tokens=1-31" %% in ("%%…") do ( %%160 in ("133")
However, it seems that some web browser don't correctly copy-paste some extended characters. If the program don't works correctly, you should check that these characters were correctly copied and fix they if necessary. You may try to copy the lines above (in pink background) and test if they were correctly copied...
Output example:
Enter tokens definition string in the same way of FOR /F "tokens=x,y,m-n" one
You may define a tokens range in descending order: "tokens=10-6" = 10 9 8 7 6
or add an increment different than 1: "tokens=10-35+5" = 10 15 20 25 30 35
Combine them: "tokens=10,28-32,170-161-3" = 10 28 29 30 31 32 170 167 164 161
The maximum token number is 177
tokens=10-6
A10 A9 A8 A7 A6
B10 B9 B8 B7 B6
C10 C9 C8 C7 C6
tokens=10-35+5
A10 A15 A20 A25 A30 A35
B10 B15 B20 B25 B30 B35
C10 C15 C20 C25 C30 C35
tokens=10,28-32,170-161-3
A10 A28 A29 A30 A31 A32 A170 A167 A164 A161
B10 B28 B29 B30 B31 B32 B170 B167 B164 B161
C10 C28 C29 C30 C31 C32 C170 C167 C164 C161
tokens=71,3
A71 A3
B71 B3
C71 C3
If your application requires less than 177 tokens, you may modify this program and eliminate the code sections of the not required tokens; that is, with 2 FOR's you may access up to 56 tokens, with 3 up to 84, with 4 up to 115, and with 5 up to 146.
You may review a detailed explanation of this method here; you may also download (a previous version of) this program in a .zip file from this post that would allow to fix the problem of the extended characters in the six FOR /F commands in a simple way...
I have a simple (I hope it doesn't become complicated) batch file in which you enter in a series of letters, (possibly seperated by spaces) and it 'decrypts them' similar to those old 'decoder wheels', in this case where A=1, B=2, and so forth
This is what I have so far, but I wish to make it so it can find what you put in all together, rather than having to enter in each letter one at a time. Thanks
echo off
cls
:1
echo Enter in letters to decrypt
set /p let=
if %let%==A echo 1
if %let%==B echo 2
if %let%==C echo 3
if %let%==D echo 4
if %let%==E echo 5
if %let%==F echo 6
if %let%==G echo 7
if %let%==H echo 8
if %let%==I echo 9
if %let%==J echo 10
if %let%==K echo 11
if %let%==L echo 12
if %let%==M echo 13
if %let%==N echo 14
if %let%==O echo 15
if %let%==P echo 16
if %let%==Q echo 17
if %let%==R echo 18
if %let%==S echo 19
if %let%==T echo 20
if %let%==U echo 21
if %let%==V echo 22
if %let%==W echo 23
if %let%==X echo 24
if %let%==Y echo 25
if %let%==Z echo 26
CHOICE /C ABCDEFGHIJKLMNOPQRSTUVWXYZ /N
echo %errorlevel%
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am almost done with my game and have employed "Alternate Data Streams" to save some high scores in a ADS. Now i tried to do the same with a color option, to make the game be the same color scheme you set it every time you open it until you want to change it. Here is the code that i am working on:
echo.
echo Color Options - background/text
echo ------------------
echo 0) Black
echo 1) Blue
echo 2) green
echo 3) Aqua
echo 4) Red
echo 5) Purple
echo 6) Yellow
echo 7) White
echo 8) Grey
echo ------------------
set /p BcolorSetting=Background:
set /p TcolorSetting=Text:
echo %BcolorSetting%%TcolorSetting% >>"%~f0:colors"
color <"%~f0:colors"
pause
If you want to see the whole thing it's...
#echo off
REM Produced by Calder Hutchins
REM This is a game
title Memory Game
:begin
set point=0
cls
echo.
echo Memeory Game
echo ------------------
echo 1) Play
echo 2) Instructions
echo 3) High Scores
echo 4) Options
echo ------------------
set /p pick=^>
if %pick%==1 goto one
if %pick%==2 goto two
if %pick%==3 goto three
if %pick%==4 goto four
if %pick%==99 goto test
goto begin
:one
cls
REM Determines the number
if %point% LSS 6 set /a rand=%random% %% (100 - 1 + 1)+ 1
if %point% LSS 12 if %point% GTR 5 set /a rand=%random% %% (500 - 100 + 1)+ 100
if %point% LSS 18 if %point% GTR 11 set /a rand=%random% %% (1000 - 500 + 1)+ 500
if %point% LSS 24 if %point% GTR 17 set /a rand=%random% %% (2000 - 1000 + 1)+ 1000
if %point% LSS 30 if %point% GTR 23 set /a rand=%random% %% (9000 - 1500 + 1)+ 1500
if %point% LSS 36 if %point% GTR 29 set /a rand=%random% %% (19000 - 5000 + 1)+ 5000
if %point% LSS 42 if %point% GTR 35 set /a rand=%random% %% (32000 - 10000 + 1)+ 10000
if %point% LSS 48 if %point% GTR 41 set /a rand=%random% %% (999 - 100 + 1)+ 100
if %point% LSS 48 if %point% GTR 41 set /a randtwo=%random% %% (999 - 100 + 1)+ 100
if %point% GTR 47 set /a rand=%random% %% (9999 - 1000 + 1)+ 1000
if %point% GTR 47 set /a randtwo=%random% %% (9999 - 1000 + 1)+ 1000
echo.
REM Prints the number
if %point% LSS 42 echo %rand%
if %point% GTR 41 set rand=%rand%%randtwo%
if %point% GTR 41 echo %rand%
echo.
ping localhost -n 3 >nul
cls
echo.
echo.
echo.
set /p yourOption=Guess:
REM Determines correct or wrong
if %youroption%==%rand% set /a point=%point% +1 & goto one
cls
echo.
echo You scored: %point%
echo.
set /p name=Type name:
echo %name% - %point% >>"%~f0:scores"
goto begin
:two
cls
echo.
echo The objective of the game is to get as many points as possible. To get points you must correctly retype the numbers that appear on the screen. The numbers show for a short period of time. As you get more points the numbers get longer! When you have lost you will be prompted to enter your name. You can view the highscores too!
echo.
pause
goto begin
:three
cls
echo.
more<"%~f0:scores" | sort
echo.
pause
goto begin
:four
cls
echo.
echo Settings/Options
echo ------------------
echo 1) color
echo ------------------
set /p pickSetting=^>
if %pickSetting%==1 goto oneSetting
goto four
:oneSetting
cls
echo.
echo Color Options - background/text
echo ------------------
echo 0) Black
echo 1) Blue
echo 2) green
echo 3) Aqua
echo 4) Red
echo 5) Purple
echo 6) Yellow
echo 7) White
echo 8) Grey
echo ------------------
set /p BcolorSetting=Background:
set /p TcolorSetting=Text:
echo %BcolorSetting%%TcolorSetting% >>"%~f0:colors"
color <"%~f0:colors"
pause
goto begin
Thank-you in advance guys!
Fortunately the FOR /F can read ADS:
for /f "usebackq" %%C in ("%~f0:colors") do COLOR %%C
It appears that you will have to CD a certain directory. Then, write to a text file within the directory. In the start, read the text file.
Then, overwrite the text file and write the color in it at the point you are stuck in.
If you need to start with settings in any app, you always need a save file.
Writing can be like this:
echo %BcolorSetting%%TcolorSetting% >>"colorsetting.txt"
And when retrieving, do it in the very beginning. Before begin.
It is read like this
set /p %~f0:colors= <colorsetting.txt
Assuming you use those variables. I hope this helps.