How to check if a parameter (or variable) is a number in a Batch script

后端 未结 10 499
南方客
南方客 2020-12-01 08:02

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 a

相关标签:
10条回答
  • 2020-12-01 08:52

    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

    • You get support for octal and hexadecimal numbers by prefixing them with 0 or 0x.
    • If someone uses a very small or large number such as -9999999999999 or 9999999999999 then XVALUE will be set to the minimum or maximum allowed values which are -2147483648 and 2147483647.
    • If someone uses garbage such as the word "hello" then XVALUE is set to 0. If it's something like 123x456 then the parser stops at the "x" and XVALUE is set to 123.
    0 讨论(0)
  • 2020-12-01 08:54

    @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"
    
    0 讨论(0)
  • 2020-12-01 09:02

    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

    0 讨论(0)
  • 2020-12-01 09:03

    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
    
    0 讨论(0)
提交回复
热议问题