使用 Batch 解决“findstr”问题

问题描述 投票:0回答:3

下面,我写了一些代码。它会检测 Micro-SD 卡是否插入计算机,如果插入,它会要求输入您的 PIN 码。输入 PIN 码后,它将在卡片中查找包含 PIN 码列表的文本文件。

:start
cls
echo.
echo.
if exist E:\ (
    goto enterPin
) else (
    echo INSERT YOUR CARD
)
timeout 1 >nul
goto start


:enterPin
echo Enter Account Pin: %chip%
set /p pin=": "

:: Finding the specified pin
findstr /m "%pin%" E:\Chip\CardInfo.txt >Nul
if %errorlevel%==0 (
    echo Pin "%pin%" is valid
    timeout 1 >nul
    goto account
)

if %errorlevel%==1 (
    echo Pin "%pin%" is invalid
    pause
    goto start
)

:account
cls

:: Finds the name of the account owner and continues
setlocal enableextensions disabledelayedexpansion
for /F "tokens=2 delims=/" %%a in ('findstr /I "%pin%/" E:\Chip\CardInfo.txt') do set "user=%%a"  
for /F "tokens=3 delims=/" %%b in ('findstr /I "%pin%/%user%/" E:\Chip\CardInfo.txt') do set "balance=%%b"  
echo.
echo.
echo Welcome, %user%.
echo.
echo ACCOUNT BALANCE: $%balance%
echo.
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
choice /c 1234 >nul 
if %ERRORLEVEL% EQU 1 goto deposit
if %ERRORLEVEL% EQU 2 goto withdraw
if %ERRORLEVEL% EQU 3 exit
if %ERRORLEVEL% EQU 4 goto account

:deposit
echo.
echo.
set /p add="Money to Deposit: "
set /a moneytoadd=%balance%+%add%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /f E:\Chip\CardInfo.txt /o -
goto account

:withdraw
echo.
echo.
set /p sub="Money to Withdraw: "
set /a moneytosub=%balance%-%sub%
call jrepl "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /f 
E:\Chip\CardInfo.txt /o -
goto account
endlocal

问题就出现了。一个 PIN 码由 4 个数字字符组成(例如 1234),但是如果有两个 PIN 码具有相同的字符(例如 1234、6543),它会显示该 PIN 码已验证。例如,如果我输入 4,它只会在文件中查找数字 4。并会说该引脚有效。 尽管如此,只是数字 4 并不是现有的 pin。我的猜测是这是“findstr”的一个缺陷。但我不确定。

“CardInfo.txt”的内容:

1234/Test User/1000
6543/Another Test User/2000
windows batch-file cmd command-line
3个回答
1
投票

使用正则表达式(使用

<StartOfLine><PIN></>
):

findstr /m "^%pin%/" E:\Chip\CardInfo.txt >Nul

其中

^
是“行的开头”。


1
投票

这正是您想要的:

@echo off
::add your path below
for /f %%a in (file.txt) do (
   call :funch %%a  
)
:funch
set input=%1
set "modifiedinput=%input:~0,4%"
set /p pin=Enter Account Pin:
if %modifiedinput% equ %pin% ( goto authentication_passed) else ( goto authentication_failed)
:authentication_passed
echo auth passed
rem your code
pause >nul
exit
:authentication_failed
echo auth failed
goto funch


它将从文件中读取输入,然后提取前四个字符,在您的情况下是引脚。


1
投票

我重写了整个批处理文件,以便在执行时更加安全:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem endlocal is executed implicitly by cmd.exe on exiting batch file processing.

:Begin
cls
echo(
echo(
if exist E:\ goto enterPin
echo INSERT YOUR CARD
%SystemRoot%\System32\timeout.exe /T 1 >nul
goto Begin

:enterPin
set "pin="
set /p pin="Enter account pin for %chip%: "
if not defined pin goto enterPin
set "pin=%pin:"=%"
if not defined pin goto enterPin
for /F delims^=01234567890^ eol^= %%I in ("%pin%") do goto enterPin

rem Finding the specified pin.
%SystemRoot%\System32\findstr.exe /B /L /M /C:"%pin%/" E:\Chip\CardInfo.txt >Nul
if errorlevel 1 (
    echo Pin "%pin%" is invalid.
    pause
    goto Begin
)

echo Pin "%pin%" is valid.
%SystemRoot%\System32\timeout.exe /T 1 >nul

:account
cls

rem Finds the name of the account owner and continues
for /F "tokens=2,3 delims=/" %%I in ('%SystemRoot%\System32\findstr.exe /B /L /C:"%pin%/" E:\Chip\CardInfo.txt') do set "user=%%I" & set "balance=%%J"
echo(
echo(
echo Welcome, %user%.
echo(
echo ACCOUNT BALANCE: $%balance%
echo(
echo 1=Deposit / 2=Withdraw / 3=Exit / 4=Refresh
%SystemRoot%\System32\choice.exe /c 1234 >nul
if not errorlevel 1 goto account
if errorlevel 4 goto account
if errorlevel 3 exit /B
if errorlevel 2 goto withdraw

:deposit
echo(
echo(
set "add="
set /P "add=Money to deposit: "
set /A moneytoadd=balance + add
call "%~dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytoadd%" /L /f E:\Chip\CardInfo.txt /o -
goto account

:withdraw
echo(
echo(
set "sub="
set /P "sub=Money to withdraw: "
set /A moneytosub=balance - sub
call "%dp0jrepl.bat" "%pin%/%user%/%balance%" "%pin%/%user%/%moneytosub%" /L /f E:\Chip\CardInfo.txt /o -
goto account

此代码修复的问题:

  1. 有命令START。因此,不建议使用字符串
    start
    作为标签,尽管这是可能的。
  2. 如果也可以使用带有 GOTO 的简单 IF 条件,建议避免使用 IF (...) ELSE (...) 条件。
  3. 尽可能使用完全限定文件名,以避免批处理文件无法在环境变量上按预期运行
    PATH
    (太频繁)或
    PATHEXT
    (很少)在用户计算机上损坏。
  4. 用户可以自由地输入由
    set /P
    完成的任何提示,从无到有,导致进一步处理语法错误,并在未准备好任何用户输入的代码上立即退出批处理文件执行。因此,第一个
    set /P
    提示得到了改进,并验证用户是否输入了仅包含数字的字符串。
  5. 使用 FINDSTR 是通过附加选项来完成的,仅在行首查找引脚(区分大小写)并进行文字搜索,并且下一个字符必须是斜杠字符。
  6. 代码中使用了ERRORLEVEL评估的推荐语法。
  7. 算术表达式是使用推荐的语法编写的,即使用户什么都不输入或根本无法转换为整数的字符串也能工作。
  8. 命令 EXIT 与选项
    /B
    一起使用,仅退出批处理文件的处理,而不是整个命令过程。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • call /?
  • choice /?
  • cls /?
  • echo /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?
  • timeout /?

有关代码改进的有用页面:

© www.soinside.com 2019 - 2024. All rights reserved.