【问题标题】:Batch file input validation and limitation批处理文件输入验证和限制
【发布时间】:2011-12-12 16:19:27
【问题描述】:

我有一个批处理文件来帮助客户自动备份他们的文件,但是它对他们的编辑不友好,所以我打算让客户输入一个字母作为他们备份的目标驱动器。

问题是,我不知道如何将他们的输入限制为只有一个字符并且只有 a-z

我已阅读此资源> Batch File input validation - Make sure user entered an integer 。但还是想不出任何解决办法

问题是,我们真的可以限制输入长度和验证吗?有什么可以参考的吗?

这是我的代码

: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

【问题讨论】:

  • 您可以使用 choise 只获取一个字符(Vista、Win7)
  • 但这大约是。 23 种选择,但我会尝试的

标签: batch-file


【解决方案1】:

以下使用基本的 cmd 语法。它将循环直到用户输入一个小写字符。

: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%

【讨论】:

  • 您的解决方案更简单,喜欢它。但是由于脚本的紧迫性,我必须在没有用户输入的情况下修复我的脚本。不过,我打算用用户输入再做一个
  • 这个解决方案是区分大小写的 - 大写字母不起作用,但它们可能应该。
  • @Gilles Arcas 你能分解一下"%choice:~1,1%"=="" 是如何将输入限制为 1 个字符的吗?另外,听起来if 语句是在说if choice is less than "a" and greater than "z", try again. 这如何允许在a 和z 之间添加驱动器号?还有@dbenham,添加IF /I 使其不区分大小写。
【解决方案2】:

原始的 BATCH 命令无法做到这一点;但是,您可以使用第三方程序。例如,下面的批处理文件创建 GETKEY.COM 文件:

@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

您必须拥有 DEBUG.COM 才能使其工作。 GETKEY 读取一个键并在 ERRORLEVEL 中返回其 ASCII 码,读取的键不会回显到屏幕上。您必须操作返回的值以检查是否在所需范围内,然后将其转换为等效字母:

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%

您甚至可以通过这种方式处理功能键和特殊键...

【讨论】:

  • 我在哪里可以得到这个“debug.com”?那些 echo 命令是做什么的?有什么参考吗?
  • 它是最初用汇编语言编写的可执行程序的代码(8字节长)。您可能会从该站点获得 DEBUG,但请先检查尚未安装在您的计算机中:ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/…
  • 如何检查我是否有DEBUG?
  • 在命令提示符处输入:DEBUG;如果 DEBUG 启动,输入 Q 并回车退出。
【解决方案3】:

如果您使用的是 Vista 或更高版本,则可以使用 CHOICE 命令(键入“CHOICE /?”获取文档)默认情况下,CHOICE 不区分大小写,我认为这对您的情况来说是件好事。

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!"

这里是 Giles Arcas 后输入验证策略的一种变体,它允许大写和小写。它也更加健壮,因为它可以正确处理空字符串。这应该适用于 XP 及更高版本。

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

这是另一个使用 FINDSTR 正则表达式来验证条目的变体

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

建议延迟扩展,以防用户输入"&"&之类的字符串

【讨论】:

    【解决方案4】:

    您可以将 ReadFormattedLine 子例程用于所有类型的格式化输入。例如,下面的命令只读取一个字母:

    call :ReadFormattedLine drive="L" /M "Under which drive will you save the backup? "
    

    这个子程序是用纯批处理编写的,所以它不需要任何额外的程序,它允许多种格式化输入操作,比如读取密码。在前面的例子中,子程序在用户按下一个字母后自动继续,所以它不需要 Enter 键。您可以从Read a line with specific format 下载 ReadFormattedLine 子程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-14
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多