Reputation: 83
I have a batch file to help clients do automated backup of their files, however it's not editing friendly to them, so I plan to make the clients input a letter for the destination drive of their backup.
The problem is, I do not know how to limit their input to only one characters and only a-z
I have read this resource > Batch File input validation - Make sure user entered an integer . But still can't figure out any solution
The question is, do we really can limit the input length and the validation thing? are there any reference can use on this matter?
here is my code
:init
@echo off
color 02
REM -- set vars
set tgl=%DATE:~0,2%
set bln=%DATE:~-7,2%
set thn=%DATE:~-4,4%
set jam=%TIME:~0,2%
if "%time:~0,1%"==" " set jam=0%TIME:~1,1%
set menit=%TIME:~3,2%
set detik=%TIME:~6,2%
echo Under which drive will you save the backup? ( one letter only, a-z )
set /p drive=
pause
cls
:stopsvc
net stop svc01
cls
echo stop service [OK]
echo copy files [ ]
echo start service [ ]
echo archiving [ ]
echo.
REM -- start backup
echo.
:copy
echo copying ...
xcopy /e /y c:\docs %drive%:\data\docs\
cls
echo stop service [OK]
echo copy files [OK]
echo start service [ ]
echo archiving [ ]
echo.
echo.
:startsvc
echo starting MySQL service...
net start svc01
if errorlevel = 1 goto svcfail
echo.
echo done
cls
echo stop service [OK]
echo copy files [OK]
echo start service [OK]
echo archiving [ ]
echo.
echo.
echo backup successfully created
echo now archiving ...
echo.
:archive
cd "%drive%:\data"
ren "docs" "BACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%"
echo archiving - OK
cls
echo stop service [OK] > "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo copy files [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start service [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo archiving [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo.
echo.
echo buhbye
echo copyright(c) [SC] 2010-2011
pause
goto eof
:svcfail
echo cannot start svc01 service > "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start it manually through services.msc >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo.
echo.
echo stop service [OK]
echo copy files [OK]
echo start service [FAIL]
echo archiving [ ]
pause
goto archive1
:archive1
cd "%drive%:\data"
ren "docs" "BACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%"
echo archiving - OK
cls
echo stop service [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo copy files [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start service [FAIL] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo archiving [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo.
echo.
echo all done~!
pause
goto eof
:eof
exit
Upvotes: 1
Views: 7591
Reputation: 67296
You may use ReadFormattedLine subroutine for all kind of formatted input. For example, the command below read just one letter:
call :ReadFormattedLine drive="L" /M "Under which drive will you save the backup? "
This subroutine is written in pure Batch so it does not require any additional program, and it allows several formatted input operations, like read passwords. In previous example, the subroutine automatically continue after the user press a letter, so it does not require Enter key. You may download ReadFormattedLine subroutine from Read a line with specific format.
Upvotes: 0
Reputation: 130919
If you are using Vista or later, you can use the CHOICE command (type 'CHOICE /?' for documentation) By default, CHOICE is case insensitive, which I think is a good thing for your situation.
setlocal enableDelayedExpansion
set "choices=abcdefghijklmnopqrstuvwxyz"
echo Under which drive will you save the backup? ( one letter only, a-z )
choice /c %choices% /n
set /a "n=%errorlevel%-1"
set "drive=!choices:~%n%,1!"
Here is a variation of Giles Arcas strategy of post entry validation that allows both upper and lower case. It is also a bit more robust in that it handles empty strings properly. This should work on XP and later.
setlocal enableDelayedExpansion
set "choices=abcdefghijklmnopqrstuvwxyz"
:select
echo Under which drive will you save the backup? ( one letter only, a-z )
set "drive="
set /p "drive="
for /l %%N in (0 1 25) do if /i "!choices:~%%N,1!"=="%drive%" goto :continue
goto :select
:continue
Here is another variation that uses a FINDSTR regular expression to validate the entry
setlocal enableDelayedExpansion
:select
echo Under which drive will you save the backup? ( one letter only, a-z )
set "drive="
set /p "drive="
echo !drive!|findstr /r /i "^[abcdefghijklmnopqrstuvwxyz]$" >nul || goto :select
The delayed expansion is advised in case the user enters a string like "&"&
Upvotes: 1
Reputation: 2722
The following uses basic cmd syntax. It will loop until user enter a single lowercase character.
:choice
set /p choice=Under which drive will you save the backup? ( one letter only, a-z )
if not "%choice:~1,1%"=="" goto choice
if "%choice%" lss "a" goto choice
if "%choice%" gtr "z" goto choice
set drive=%choice%
Upvotes: 4
Reputation: 67296
There is no way to do that with the original BATCH commands; however, you may use a third party program. For example, the Batch file below create GETKEY.COM file:
@ECHO OFF
REM CREATE THE GETKEY.COM AUXILIARY FILE
(
ECHO E100
ECHO B4 08 CD 21 B4 4C CD 21
ECHO RCX
ECHO 8
ECHO W
ECHO Q
) | DEBUG GETKEY.COM > NUL
You must have DEBUG.COM in order for this to work. GETKEY read a key and return its ASCII code in ERRORLEVEL, the key read is NOT echoed to the screen. You must manipulate the value returned to check that is into the desired range, and then convert it to the equivalent letter:
set aLetter=97
set zLetter=122
set lowcaseLetters=a b c d e f g h i j k l m n o p q r s t u v w x y z
REM Read a key and check that it is in range
:readKey
getkey
set key=%errorlevel%
if %key% LSS %aLetter% goto readKey
if %key% GTR %zLetter% goto readKey
REM Convert ASCII code to an index between 1 and 26
set /A index=key-aLetter+1
REM Get the letter and echo it in the screen
for /F "tokens=%index%" %%a in ("%lowcaseLetters%") do set letter=%%a
echo %letter%
You may even process function and special keys this way...
Upvotes: 1