Nella riga di comando basata su Windows NT (principalmente per XP o versioni successive), c'è un modo per verificare se uno switch fornito è solo un numero? A seconda del numero, voglio che esegua il ciclo attraverso il codice x il numero di volte
Nella riga di comando basata su Windows NT (principalmente per XP o versioni successive), c'è un modo per verificare se uno switch fornito è solo un numero? A seconda del numero, voglio che esegua il ciclo attraverso il codice x il numero di volte
Risposte:
Modificato per correggere la regex secondo il commento di Debham . Si scopre che l'aggiunta di uno spazio prima della pipe dopo l'eco aggiunge uno spazio alla stringa di pipe, che era ciò che interrompeva in precedenza l'inizio / fine della linea. Il regex potrebbe essere ulteriormente migliorato scartando gli spazi bianchi all'inizio e alla fine.
C'è il findstrcomando. Può cercare file con espressioni regolari, proprio come grepin Linux. Può anche cercare input convogliati.
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if %errorlevel% equ 0 (
echo Valid number
)
Il parametro utilizzato è impostato nella paramvariabile. Tuttavia, non c'è nulla che ti fermi usando direttamente il parametro ( %1per il primo parametro).
findstrviene utilizzato per cercare /rregex nell'input convogliato con il flag.
Il modello:
^ significa l'inizio della riga.
[0-9]significa una cifra. I *mezzi il precedenti ripetuto zero o più volte. Quindi [0-9][0-9]*significa una cifra, più zero o più cifre. In altre parole, almeno una cifra. I +una o più volte non sembra essere supportata da findstr. Si noti che [1-9]viene utilizzato per la prima cifra per non consentire gli zeri iniziali - vedere i commenti.
$ significa fine della linea.
Ora, un ciclo for in batch per x numero di volte ... se x non è un numero valido, il loop in realtà non viene eseguito affatto - viene semplicemente ignorato per la riga successiva. Quindi non è necessario verificare se l'ingresso è un numero valido!
@echo off
set param=%1
for /l %%a in (1,1,%param%) do (
echo %%a
)
Il ciclo viene eseguito utilizzando for /l, dove (x,y,z)significa start at x, incrementa di yfino al zraggiungimento. E imposta %%asul numero / iterazione corrente.
Nota: questo in realtà fallisce se c'è uno zero iniziale, facendo sì che il processore dei comandi lo tratti come un numero ottale. Vedi la risposta di dbenham per una soluzione migliore.
"this 1 fails"The FINDSTR dovrebbe fare una corrispondenza esatta. Non dovrebbe corrispondere a una parola.
09o 010potrebbe causare problemi a causa della notazione ottale. Vedi la mia risposta per regex che non consente la notazione ottale.
Quanto segue funziona molto bene per me. SET /a param=%1+0restituisce sempre 0se %1è vuoto o non numerico. Altrimenti, fornisce il numero indicato.
SET /a param=%1+0
IF NOT %param%==0 ECHO Valid number
Questo rileverà se il primo parametro è un numero naturale valido (numero intero non negativo).
@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
)
Se si desidera consentire le virgolette attorno al numero, quindi
@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
)
Nota: gli zeri iniziali non sono consentiti perché batch li tratta come ottali, quindi un valore come 09non è valido e 010ha un valore di 8.
Ispirato dalla risposta eccellente di Bob con le seguenti aggiunte
:::::::::::::::
::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^>
Il problema con quanto segue è che restituisce sempre "Numero valido" perché "se il livello di errore 0" è sempre vero a causa del fatto che è un confronto "> = 0", non un confronto "== 0".
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if errorlevel 0 (
echo Valid number
)
i miei $ 0,02
Puoi convalidare qualsiasi variabile se il suo numero:
SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")
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
Non so perché ma sul mio sistema il findstrcomando non ha funzionato. Il livello di errore non veniva modificato in corrispondenza o nessuna corrispondenza.
Ho escogitato un altro metodo però
:: 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
)
: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.
Ecco un gioco che utilizza questa funzione.
@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
set /a NO_LINES=%~1.; 2if %NO_LINES% NEQ %~1 goto ABORT. Quando i due sono uguali - La variabile o il parametro è numerico .