배치 파일에서 숫자 입력 만 확인


10

Windows NT 기반 명령 줄 (주로 XP 이상)에서 제공되는 스위치가 숫자인지 확인하는 방법이 있습니까? 숫자에 따라 코드 x 횟수 를 반복하고 싶습니다.


1
개인적으로, 나는이 답변의 방법을 선호합니다 : 사용자가 integer를 입력했는지 확인하십시오 . 명령 프로세서를 사용하여 모든 작업 을 수행 하십시오 . 최소한의 솔루션으로 2 x 라인으로 단순화 할 수 있습니다. 1 set /a NO_LINES=%~1.; 2 if %NO_LINES% NEQ %~1 goto ABORT. 둘이 같을 때-변수 또는 매개 변수 는 숫자 입니다.
됩니다

답변:


18

debham의 설명에 따라 정규 표현식을 수정하도록 편집되었습니다 . echo 후 파이프 앞에 공백을 추가하면 파이프 문자열에 공백이 추가되어 이전에 일치하는 줄의 시작 / 끝이 끊어졌습니다. 정규식은 시작과 끝에서 공백을 버림으로써 더 향상 될 수 있습니다.


있다 findstr명령. grepLinux에서 와 같이 정규 표현식으로 파일을 검색 할 수 있습니다 . 파이프 입력을 검색 할 수도 있습니다.

@echo off

set param=%1

echo %param%| findstr /r "^[1-9][0-9]*$">nul

if %errorlevel% equ 0 (
    echo Valid number
)

설명

사용 된 매개 변수는 param변수 로 설정됩니다 . 그러나 매개 변수를 직접 사용하는 것을 막는 것은 없습니다 ( %1첫 번째 매개 변수의 경우).

findstr/r정규식에 대한 플래그를 사용하여 파이프 된 입력을 검색하는 데 사용됩니다 .

패턴:

  • ^ 줄의 시작을 의미합니다.

  • [0-9]숫자를 의미합니다. 이는 *이전에 0 번 이상 반복되었음을 의미합니다. 따라서 [0-9][0-9]*하나의 숫자와 0 이상의 숫자를 의미합니다. 다시 말해, 적어도 하나의 숫자입니다. +한 번 이상은 지원하지 않는 것 findstr. 주 [1-9]앞에 0을 허용하는 최초의 숫자에 사용됩니다 - 주석을 참조하십시오.

  • $ 줄의 끝을 의미합니다.


이제 x 회 반복되는 for 루프 ... x 가 유효한 숫자가 아니라면 실제로 루프가 전혀 실행되지 않습니다. 다음 줄에서는 건너 뜁니다. 따라서 입력이 유효한 숫자인지 확인할 필요가 없습니다!

@echo off

set param=%1

for /l %%a in (1,1,%param%) do (
    echo %%a
)

루프는을 사용하여 수행되며 for /l, 여기서 (x,y,z)시작 은에 도달 할 때까지 x증가합니다 . 그리고 현재 숫자 / 반복으로 설정 됩니다.yz%%a

참고 : 앞에 0이 있으면 명령 프로세서가 8 진수로 처리하므로 실제로 실패합니다. 더 나은 해결책 은 dbenham의 답변 을 참조하십시오 .


훌륭한 설명! 사용하기 쉬움
Canadian Luke

1
작성된 바와 같이,이 솔루션은 "this 1 fails"FINDSTR 과 같은 매개 변수로 실패 하며 정확히 일치해야합니다. 단어 일치를하지 않아야합니다.
dbenham

@dbenham 감사합니다. 전에 줄 일치의 시작 / 끝을 시도했지만 여분의 공간을 전달하는 에코로 인해 실패했습니다. 지금 수정했습니다.
Bob

@CanadianLuke 편집 내용을 살펴볼 수 있습니다.
Bob

09또는 010때문에 8 진수의 문제가 발생할 수 있습니다. 8 진수 표기법을 허용하지 않는 정규식에 대한 내 대답 을 참조하십시오 .
dbenham

8

다음은 저에게 매우 효과적입니다. 비어 있거나 숫자가 아닌 경우 SET /a param=%1+0항상 반환 0합니다 %1. 그렇지 않으면 주어진 숫자를 제공합니다.

SET /a param=%1+0
IF NOT %param%==0 ECHO Valid number

4
매개 변수 = 0 인 경우 실패합니다. 또한 "1 + 1"과 같은 매개 변수를 숫자로 취급하므로 요구 사항에 따라 문제가 발생할 수 있습니다.
dbenham

7

첫 번째 매개 변수가 유효한 자연수 (음수가 아닌 정수)인지 감지합니다.

@echo off
echo %1|findstr /xr "[1-9][0-9]* 0" >nul && (
  echo %1 is a valid number
) || (
  echo %1 is NOT a valid number
)

숫자 주위에 따옴표를 허용하려면

@echo off
echo "%~1"|findstr /xr /c:\"[1-9][0-9]*\" /c:\"0\" >nul && (
  echo %~1 is a valid number
) || (
  echo %~1 is NOT a valid number
)

참고-배치는 0을 8 진수로 취급하므로 앞에 오는 0은 허용되지 않으므로 값 09은 유효하지 않으며 010값은 8입니다.


3

다음과 같은 추가 사항 으로 Bob의 탁월한 답변 에서 영감을 얻었습니다.

  • 오류 수준 논리 수정
  • 숫자를 반복하고 일부 산술을 수행하는 DoWork 루프 / 서브를 구현하십시오.

:::::::::::::::
::CountTo.bat
:::::::::::::::
@echo off

::This is the number to test
if "%1"=="" goto :Usage

set param=%1
set matchPattern="^[1-9][0-9]*$"

::test if param matches matchPattern, quietly
:: (redirect stdout to nul, and stderr to stdout)

echo %param%|findstr /r %matchPattern%>nul 2>&1

:: check for errorlevel 1 or higher.  errorlevel 0 is handled as
:: an unchecked fall-through
if errorlevel 1 goto :MyHandleErrorCode

::Success (errorlevel ! >= 1) so proceed.
echo %param% is a valid number
echo  (matches findstr /r %param% %matchPattern%)
echo  findstr returned errorlevel 0

::any other code that the batch file needs to do goes here
echo.
echo Iterating from 1 to %param%
echo.
for /l %%i in (1,1,%param%) do call :DoWork %%i

::anything else,
:: .
:: .

::cleanup
:: .
:: .

::exit the batch file here, skipping embedded subroutines
goto :eof

:::::::::::::::::::::::::
:: Main work subroutine
:::::::::::::::::::::::::
:DoWork
set /a offset = %1 - 1
set /a square = %1 * %1
echo item %1
echo   offset: %offset%
echo   square: %square%
echo.
goto :eof

:::::::::::::::::::::::
:: Error handler code
:::::::::::::::::::::::
:MyHandleErrorCode
echo.
echo CountTo %param%
echo   %param% is not a valid number
echo   (does not match findstr /r %param% %matchPattern%)
echo   findstr returned errorlevel ^>= 1
:: error code doesn't have a goto :eof, we want to drop through to :Usage

::::::::
:Usage
::::::::
echo.
echo Usage:
echo.   CountTo ^<someNumber^>

다음의 문제는 '== 0'비교가 아니라 '> = 0'비교이기 때문에 '오류 수준 0'인 경우 항상 참이므로 항상 '유효한 숫자'를 반환한다는 것입니다.

@echo off

set param=%1

echo %param%| findstr /r "^[1-9][0-9]*$">nul

if errorlevel 0 (
    echo Valid number
)

내 $ .02


으악 ... 내 오류 수준을 수정했습니다. 자동 폴스 루가 아닌 직접 수치 비교.
Bob

2

다음과 같은 경우 변수를 확인할 수 있습니다.

SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")

0
set xx=33
echo %xx%
SET /a %xx%+0 2>nul >nul && echo all Digits


set xx=3x3
echo %xx%
SET /a %xx%+0 2>nul >nul || echo No Digits

2
설명도 추가해 주시겠습니까?
slhck

0

왜 그런지 모르겠지만 시스템에서 findstr명령이 작동하지 않았습니다. 일치시 오류 수준이 변경되지 않았거나 일치하지 않았습니다.

그래도 다른 방법을 생각해 냈습니다.

:: Look for all digits. Parse the string and use all the digits as
:: delimiters. If the entire string is a digit then we will get an empty
:: parse value.
SET ALL_DIGITS=0
FOR /F "tokens=* delims=0123456789" %%a IN ("%VALUE%") DO (
    IF "[%%a]" EQU "[]" SET ALL_DIGITS=1
)

IF %ALL_DIGITS% EQU 0 (
    ECHO ERROR: %VALUE% is not all numbers
)

-1
:main 
set /p input=text
if %input% equ 0 goto valid
set /a inputval="%input%"*1
if %inputval% equ 0 goto invalid
goto valid

:invalid
echo Input is not an integer.

:valid
echo Input is an integer.

이 기능을 사용하는 게임은 다음과 같습니다.

@echo off
:main
set /a guessmin=1
set /a guessmax=100
set /a guessrand=%random% %%100 +1
echo.
:check
if %guessmin% equ %guessmax% goto fail
set /p input=- Pick a number %guessmin% - %guessmax%: 
set /a inputval="%input%"*1
if %inputval% equ 0 goto invalid
if %inputval% gtr %guessmax% goto invalid
if %inputval% lss %guessmin% goto invalid
if %inputval% gtr %guessrand% goto high
if %inputval% lss %guessrand% goto low
if %inputval% equ %guessrand% goto mid
:invalid
echo   Please enter a valid number.
echo.
goto check
:high
echo   Your guess was too high.
echo.
set /a guessmax=%inputval%-1
goto check
:low
echo   Your guess was too low.
echo.
set /a guessmin=%inputval%+1
goto check
:mid
echo   Your guess was correct. The game will now reset.
set /p input=- Press enter to play again.
cls
goto main
:fail
echo   You actually managed to lose because there is only
echo   one number remaining. That number is %guessrand%.
set /p input=- Press enter to lose again.
cls
goto main
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.