【问题标题】:Extract number from the command line output by batch file通过批处理文件从命令行输出中提取数字
【发布时间】:2017-05-26 13:41:53
【问题描述】:

我有一个将提交证书请求的批处理脚本,它将在 CMD 中返回多个 RequestId。我希望批处理文件提取所有数字并将其与名为 RequestID 的文件名逐行存储在一个文件中。

这是执行脚本后命令行的输出

 C:\OpenSSL\bin>RequestCert.bat
 Generating a 2048 bit RSA private key
 ...................................................................+++
 ...........+++
 writing new private key to 'xxxx'
 -----
 No value provided for Subject Attribute ST, skipped
 RequestId: 1892
 RequestId: "1892"
 Certificate request is pending: Taken Under Submission (0)
 Generating certificate request and key for xxxx
 ECHO is off.
 ------------------------------------------------------------------------
 Generating a 2048 bit RSA private key
 ........+++ 
 ...........................................................................
 ..........+++
 writing new private key to 'xxxx'
 -----
 No value provided for Subject Attribute ST, skipped
 RequestId: 1893
 RequestId: "1893"
 Certificate request is pending: Taken Under Submission (0)
 Generating certificate request and key for xxxx
 ------------------------------------------------------------------------
 Please approve the certificates before pressing enter.
 Please approve the certificates before pressing enter.
 Please approve the certificates before pressing enter.
 Press any key to continue . . . 

所以代码应该提取出RequestId后面的数字:

RequestId: 1892
RequestId: 1893

文件应该有:

 1892
 1893

然后它将获取文件的第一个数字和最后一个数字并将其回显。 例如,请批准从 Request ID 900 到 920 的证书。

这是我尝试过的:

for /f "tokens=2 delims=:" %%b in ('"C:\program Files\command.exe"'|find 
"RequestId : ") do (
 echo %%b >> RequestID.txt
)

【问题讨论】:

    标签: batch-file


    【解决方案1】:

    为了测试下面的批处理代码,我创建了文件Input.txt,其中包含以下行:

    No value provided for Subject Attribute ST, skipped
    RequestId: 1892
    RequestId: "1892"
    Certificate request is pending: Taken Under Submission (0)
    Generating certificate request and key for xxxx
    No value provided for Subject Attribute ST, skipped
    RequestId: 1893
    RequestId: "1893"
    Certificate request is pending: Taken Under Submission (0)
    Generating certificate request and key for xxxx
    

    下面的批处理代码被写入文件GetNumbers.bat,存储在与Input.txt相同的目录中。

    @echo off
    del Output.txt 2>nul
    for /F "tokens=1,2" %%I in (Input.txt) do if "%%I" == "RequestId:" if %%J == %%~J echo %%J>>Output.txt
    

    在命令提示符窗口中执行批处理文件时,当前目录是具有Input.txtGetNumbers.bat 的目录,通过键入批处理文件名并点击键 RETURN 没有显示错误并且批处理文件使用两行创建Output.txt

    1892
    1893
    

    这样编码任务就完成了。

    FOR 命令处理文件Input.txt 中的每一行不为空或以分号开头。

    它使用普通空格和水平制表符作为字符串分隔符将每一行分成子字符串(标记)。

    第一个空格/制表符分隔的字符串被分配给循环变量I,因为tokens=1,2第二个被分配给循环变量JI之后ASCII table中的下一个字符。

    FOR的主体命令块中的命令在至少有一个标记可以分配给第一个循环变量I时执行。

    body 命令块中的 IF 条件将当前行的第一个空格/制表符分隔的字符串与RequestId: 进行比较区分大小写,以验证该行是否包含感兴趣的数字。

    如果此 IF 条件为真,则批处理代码预计第二个循环变量 J 也已设置,并且只有感兴趣的数量或双引号中的感兴趣数量。

    因此进行了比较,将循环变量J 的值与循环变量J 的值进行比较,不带双引号。在使用 IF 命令比较两个字符串时,也会考虑周围的双引号。因此,这种比较只有在 J 的数字不带双引号时才成立。

    不带双引号的数字附加到文件Output.txt

    下面的代码会慢一点但更安全:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "DoubleQuote=""
    del Output.txt 2>nul
    for /F "tokens=1,2" %%I in (Input.txt) do (
        if "%%I" == "RequestId:" if "%%~J" NEQ "" (
            set "Number=%%J"
            if "!Number:~0,1!" NEQ "!DoubleQuote!" echo !Number!>>Output.txt
        )
    )
    endlocal
    

    有了这个批处理代码循环变量J 也可以没有分配字符串或第一个批处理代码会因语法错误退出的字符串。

    在两个批处理代码块中,文件名 Input.txt 也可以替换为:

    'command line which outputs the text to process'
    

    请注意,如果字符串应被解释为要处理的行的文件名或要在后台单独命令进程中执行的命令行,则周围的直单引号会对 FOR 产生影响其中要从句柄 STDOUT 捕获并逐行处理的输出。

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

    • del /?
    • echo /?
    • endlocal /?
    • for /?
    • if /?
    • set /?
    • setlocal /?

    另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章。

    【讨论】:

    • 感谢您的帮助。真的是一篇很长的文章,需要消化很多哈哈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多