对于 /F 结合 Findstr 将文件中的特定文本存储到变量中

For /F Combined with Findstr to store a specific Text in File to a Variable

所以我有一个名为 Userdetails.dll 的文件 它包含以下内容。

ABC XYZ

DEF ZYX​​

GHI YXZ

假设每行左边的字符串是用户名,右边的字符串是密码。

现在,如何创建允许用户输入其用户名的批处理文件。然后脚本检查列表中的用户名是否有效。如果有效,则允许用户输入密码,否则退出。如果用户输入的密码与.txt 文件中提到的密码匹配,则打印"Logged in"(即Echo Logged in)。如果不是,它会回显 "Invalid Password" 并让用户循环到进入密码阶段。

我曾尝试在论坛中搜索此内容,但没有找到任何直接的 link。但是,所有 link 都让我在我的代码中使用 For /f 和 Findstr。 我需要知道如何使用 for /f 和 findstr 来提供所需的结果。 对于 /f %%A 在 ('findstr "User" userdetails.txt') d o 设置用户名=%%A

然而它return是用户名而不是用户的相关密码。 因此,我想知道如何使用命令从文件中搜索输入的用户名输入 return 密码。 注意。我不是程序员(按职业)。因此,我要求您逐行向我解释您编写的代码。非常感谢。

默认情况下 for /f 使用 space 和制表符作为分隔符对输入行进行标记,并且只读取行中的第一个标记。

由于您的输入行包含 space,仅检索该行中的第一个元素。您需要禁用定界符才能检索 for 可替换参数

中的完整行
for /f "delims=" %%a in ('
    findstr /l /c:"%whatever%" userdetails.txt
`) do set "userdetails=%%a"

或者您可以指明要检索行中的前两个标记,每个标记都存储在单独的 for 可替换参数中

for /f "tokens=1,2" %%a in ('
    findstr /l /c:"%whatever%" userdetails.txt
`) do (
    set "username=%%a"
    set "password=%%b"
)

仁慈的回答。不要让别人只为你写代码,这是被标记的好方法。

@rem Hide the commands being submitted, standard to make things not look ugly.
@echo off
rem Completely optional and useless color change.
color f0
rem Use delayed expansion for 'safer' variable handling.
rem Delayed expansion means, variables are translated to their values as they are needed, rather than having a set in stone value.
rem This means special symbols will be treated as strings instead of as a command, and a variable in a block of code can have it's value changed and read in the same block.
setlocal enableDelayedExpansion

rem Set path to the file that holds the usernames and password.
set "dataFile=C:\Users\Aresc\Desktop\userPass.txt"

:main
rem Call username method.
call :requestUsername
rem Call password method.
call :requestPassword
rem Pause,
pause
rem Then close.
exit

:requestUsername
rem Wipe the screen
cls

rem Wipe variables.
set "strUsername="
set "strCurrentUserPass="

rem Prompt for username via user input, storing into strUsername.
set /p "strUsername=Input Username:"

rem If the username is blank aka they just pressed {enter}, ask again.
if "!strUsername!" equ "" goto :requestUsername

rem Loop our datafile, line by line, grabbing the first and second word,
rem the first word is stored temp as %%G, second temp as %%H.
for /f "tokens=1,2" %%G in (!dataFile!) do (
    rem Check if the first word [username in dataFile] matches input username.
    if "!strUsername!" equ "%%G" (
        rem If it does, store the second word [the password in out dataFile] as a variable for later.
        set "strCurrentUserPass=%%H"
        rem Return to the call in ':main'.
        rem Note, a 'goto :eof' tells cmd to return to the last 'call' command location.
        rem In this case, the last call was from ':main', when i ran 'call :requestUsername'
        goto :eof
    )
)
rem If that above `for /f` loop found no matches with the `if` check, the input username wasnt valid.
exit

:requestPassword
rem Wipe variables
set "strPassword="

rem Prompt for password via user input, storing into strPassword.
set /p "strPassword=Input Password for user '!strUsername!':"

rem If the username is blank aka they just pressed {enter}, ask again.
if "!strUsername!" equ "" goto :requestPassword

rem Check if the user input matches the variable we stored from the `for /f` and `if` check.
if "!strPassword!" equ "!strCurrentUserPass!" (
    rem If it did match, do stuff, in this case echo to the screen,
    echo Logged in.
    rem then return to the call in `:main`.
    goto :eof
) else (
    rem If it did not match, tell them
    echo Invalid Password.
    rem Write a blank line, useless but it's an attempt to make a batch menu look organized.
    echo:
    rem Ask them again.
    goto :requestPassword
)
rem If there is some error with the `if` check above, exit. [Good habit.]
exit