Reputation: 16952
I need to check if a parameter that is passed to a Windows Batch file is a numeric value or not. It would be good for the check to also works for variables.
I found an answer to a similar question, where the findstr
command is used with a regular expression.
I did try that solution, but it’s not working like I hoped (at least on Windows 7).
My test scenarios are as follows:
AA # not a valid number
A1 # not a valid number
1A # not a valid number
11 # a valid number
Upvotes: 27
Views: 80309
Reputation: 1
I know that this is a quite old thread, but I ran into that problem, too. Some of the proposals given up to this point can (for example) not handle a "&" entered. And I wanted to have a "one-line" solution (no CALL etc.) that is "rock solid" regarding this kind of "poison" characters entered as (part of) keyboard input. My proposal takes a "whitelist"/"cinderella"-approach, checks the variable in question (varinput) digit by digit, simply picks out the "good" ones and concatenates them to "varcleaned".
set varcleaned=&& FOR /L %%i IN (0,1,10) DO (FOR %%j IN (A B C D 0 1 2 3 4) DO (IF "!varinput:~%%i,1!" EQU "%%j" (SET varcleaned=!varcleaned!%%j)))
I have tested it against the most common "poison" characters - and it works. In the example given the whitelist is A to D and 0 to 4 and there are 11 rounds (meaning it does its job for varinput < 12 digits). So, if you would like to have "a numeric" value as varcleaned, simply change the whitelist accordingly.
Once you have "cleaned" the variable, you could proceed with the other solutions mentioned above like set /a varinput = %varcleaned% 2>nul
. For performance reasons I would keep the number of walkthroughs and the whitelist as small as possible.
Upvotes: 0
Reputation: 57252
if errorlevel
accepts only numeric values which can be used for a checks:
set test_var=001
(
(if errorlevel %test_var% break ) 2>nul
)&&(
echo %test_var% is numeric
)||(
echo %test_var% is NOT numeric
)
set test_var=001X
(
(if errorlevel %test_var% break ) 2>nul
)&&(
echo %test_var% is numeric
)||(
echo %test_var% is NOT numeric
)
the first check will pass, the second not.
Though the script above would not handle unary +
- if you want to handle this case too check - isInteger.bat
Upvotes: 1
Reputation: 133
I use a more low tech approach. It only works with integers and supports negative values.
set "XVALUE=%~1"
set /A XVALUE=XVALUE
if "%XVALUE%" NEQ "%~1" goto :invalid_value
The first line gets the command line argument and drops it into XVALUE. Using the "quotes" prevents issues with various special characters.
The second line looks mysterious but takes advantage of that when there is a text string on the right hand side of the equals sign for SET /A that it's interpreted as an environment variable containing a numeric value. The command processor parses the presumed numeric value without generating any error messages nor setting ERRORLEVEL. Doing it this way always results in XVALUE being converted into a valid numeric value regardless of whatever was passed to us.
The third line is optional and is only needed if you want to be strict about that the argument is a numeric value in the range -2147483648 to 2147483647. If you don't use the if
test then
Upvotes: 1
Reputation: 2624
The easiest for positive integers should be:
IF 1%1 NEQ +1%1 echo Notnumeric!
If negative numbers (hyphen) are also to be considered, this will work
SET number=%1
if 1%1 EQU +1%1 echo positive number
if %1==-%number:-=% echo negative number
Learned from this article here
Upvotes: 12
Reputation: 37
Just try to divide per 1. But it doesn't work with numbers out of Z (non relative integer or decimal).
set var=29
set /a number=%var% >nul 2>&1
set /a number=%number% / 1 >nul 2>&1
if "%var%" == "%number%" (echo numeric) else (echo NOT numeric)
Upvotes: 2
Reputation: 4929
I use this function instead, it seems to work for me without any issues...
REM == Script variables =============================================
SET "NUMCODE=%1"
SET "NAME=%2"
REM == Main script ==================================================
CALL :Validate "NUMCODE"
IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL%
CALL :Validate "NAME"
IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL%
ECHO Validation Complete and all variables passed validation.
REM == Functions ====================================================
:IsNumeric [string-value] [return-val]
SET "stringVal=%~1"
SET /A numericVal=%stringVal% > nul 2> nul
IF "%stringVal%"=="%numericVal%" (SET "%~2=1") ELSE (SET "%~2=0")
EXIT /B 0
:Validate
SET PASSEDVALIDATION=0
ECHO Validating %~1...
IF "%~1"=="NUMCODE" (
ECHO - Value: %NUMCODE%
IF NOT "%NUMCODE%"=="" SET PASSEDVALIDATION=1
IF "!PASSEDVALIDATION!"=="1" (
CALL :IsNumeric %NUMCODE% RETVAL
SET PASSEDVALIDATION=!RETVAL!
)
IF "!PASSEDVALIDATION!"=="1" (
IF NOT %NUMCODE% GEQ 1 SET PASSEDVALIDATION=0
)
IF "!PASSEDVALIDATION!"=="1" (
IF NOT %NUMCODE% LEQ 526 SET PASSEDVALIDATION=0
)
IF "!PASSEDVALIDATION!"=="0" (
ECHO - The first parameter is invalid, it can not be blank.
ECHO - Valid value is a number from 1 to 526.
ECHO - Leading zeros are not valid.
)
)
IF "%~1"=="NAME" (
ECHO - Value: %NAME%
IF NOT "%NAME%"=="" SET PASSEDVALIDATION=1
IF "!PASSEDVALIDATION!"=="0" (
ECHO - The second parameter is invalid, it can not be blank.
)
)
IF "!PASSEDVALIDATION!"=="0" (
ECHO - Failed validation.
EXIT /B 1
) ELSE (
ECHO - Passed validation.
)
EXIT /B 0
C:\mytestscript.bat 10 MrTest
Validating NUMCODE...
- Value: 10
- Passed validation.
Validating NAME...
- Value: MrTest
- Passed validation.
C:\mytestscript.bat 600
Validating NUMCODE...
- Value: 600
- The first parameter is invalid, it can not be blank.
- Valid value is a number from 1 to 526.
- Leading zeros are not valid.
- Failed validation.
C:\mytestscript.bat 10
Validating NUMCODE...
- Value: 10
- Passed validation.
Validating NAME...
- Value:
- The second parameter is invalid, it can not be blank.
- Failed validation.
Upvotes: 0
Reputation: 295
You could try this. The variable passed is for example var
and %var%
is equal to 500
.
set /a varCheck=%var%
if %varCheck% == %var% (goto :confirmed) else (exit /B)
exit /B
:confirmed
:: You can use %var% here, and it should only be executed if it is numerical!
if %var%
is equal to e.g. a3453d
, then it would set varCheck
to be 0
, and because 0
is not equal to a3453d
, then it will exit batch processing.
(The exit on line 3 is just in case the if statement decides not to execute for some reason ... XD.)
Upvotes: 8
Reputation: 1089
@hornzach - You were so close and with a much simpler answer than the rest.
To hide the error message in (win 7 at least) redirect to the standard error output (2) to nul (a special file, that quietly discards the output "bit-bucket")
set /a varCheck = %var% 2>nul
Then the rest of your answer works for the 4 test cases.
Full Answer With Test Cases:
call :CheckNumeric AA "#NOT A VALID NUMBER"
call :CheckNumeric A1 "#NOT A VALID NUMBER"
call :CheckNumeric 1A "#NOT A VALID NUMBER"
call :CheckNumeric 11 "#A VALID NUMBER"
call :CheckNumeric 1.23456789012345678901234567890.123456 "#NOT A VALID NUMBER"
goto :EOF
:CheckNumeric
@ECHO.
@ECHO Test %1
set /a num=%1 2>nul
if {%num%}=={%1} (
@ECHO %1 #A VALID NUMBER, Expected %2
goto :EOF
)
:INVALID
@ECHO %1 #NOT A VALID NUMBER, Expected %2
Outputs:
Test AA
AA #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test A1
A1 #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test 1A
1A #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test 11
11 #A VALID NUMBER, Expected "#A VALID NUMBER"
Test 1.23456789012345678901234567890.123456
1.23456789012345678901234567890.123456 #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Upvotes: 5
Reputation: 101
Does the same thing as above. Have problems with special characters. However, the solution is of a different approach.
@echo off
cls
setlocal enabledelayedexpansion
if "%1"=="" (goto:eof) else (set _VAR2CHECK=%1)
for /l %%a in (0,1,9) do (
if defined _VAR2CHECK (set "_VAR2CHECK=!_VAR2CHECK:%%a=!") else (goto :end)
)
:end
if defined _VAR2CHECK (echo %1 #NOT A VALID NUMBER) else (echo %1 #A VALID NUMBER)
set "_VAR2CHECK="
endlocal
Test scenarions:
C:\>ISNUM 1A
1A #NOT A VALID NUMBER
C:\>ISNUM 11
11 #A VALID NUMBER
Upvotes: 2
Reputation: 37569
for ± integers
(test also for leading zero):
echo(%~1|findstr "^[-][1-9][0-9]*$ ^[1-9][0-9]*$ ^0$">nul&&echo numeric||echo not numeric
Upvotes: 15
Reputation: 79983
SET "var="&for /f "delims=0123456789" %%i in ("%1") do set var=%%i
if defined var (echo %1 NOT numeric) else (echo %1 numeric)
Replace %1
with %yourvarname%
as appropriate
Upvotes: 61