如何通过批处理脚本提取两个特定字符串之间的一行的一部分

如何通过批处理脚本提取两个特定字符串之间的一行的一部分

我正在尝试提取testid=和之间的字符串]

输入文本文件

SEVERE  TEST 11/18/2019 8:00:41 AM  Could not find INPUT with [testid=2345]
SEVERE  TEST 11/18/2019 5:02:11 AM  Could not find INPUT with [testid=12345678]

预期输出

2345
12345678

答案1

尝试这个,

@echo off
for /F "tokens=* USEBACKQ" %%F in (`findstr /I /C:"8:00:41" text.txt`) do (
set string=%%F
)
set string=%string:~68%
set string=%string:~,-1%
echo %string%
for /F "tokens=* USEBACKQ" %%F in (`findstr /I /C:"5:02:11" text.txt`) do (
set string2=%%F
)
set string2=%string2:~68%
set string2=%string2:~,-1%
echo %string2%
pause

您将得到的输出是,

2345
12345678
Press any key to continue...

如果你想去掉最后一点,可以替换

pause

最后,

pause > nul

您将得到的输出是

2345
12345678

答案2

您可以使用 vbscript 中的 Regex 通过批处理文件来完成此操作:

@echo off
Title Extract Data between string and char from a text file using RegExp
Set "InputFile=Test.txt"
Set "OutputFile=OutputFile.txt"
Call :ExtractData "%InputFile%" "%OutputFile%"
If Exist %OutputFile% Start "" %OutputFile%
Exit
::-----------------------------------------------------------------------------------
:ExtractData <InputFile> <OutputFile>
(
    echo WScript.StdOut.WriteLine Extract("%~1"^)
    echo Function Extract(Data^)
    echo Dim strPattern,strResult,oRegExp,Match,colMatches 
    echo Data = WScript.StdIn.ReadAll
    echo strPattern = "\[testid=(.+)\]"
    echo Set oRegExp = New RegExp
    echo oRegExp.Global = True
    echo oRegExp.Multiline = True
    echo oRegExp.IgnoreCase = True 
    echo oRegExp.Pattern = strPattern
    echo set colMatches = oRegExp.Execute(Data^)
    echo For Each Match in colMatches
    echo    strResult = strResult ^& Match.SubMatches(0^) ^& vbcrlf
    echo Next
    echo Extract = strResult
    echo End Function
)>"%tmp%\%~n0.vbs"
cscript //nologo "%tmp%\%~n0.vbs" < "%~1" > "%~2"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------

输出文件如下:

2345
12345678

答案3

testid= 该批处理文件将提取每行(第一个)(如果有)和(第一个)后续(如果有)之间的文本],无论它们出现在行中的什么位置,但有一个例外我可以识别(参见答案的底部):

@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%L in (input.txt) do (
    set line=%%L
    set right1=!line:*testid=!
    if not !line! == !right1! (
        set left=!right1:~0,1!
        if "!left!" == "=" (
            set right2=!right1:~1!
            for /f "tokens=1 delims=]" %%W in ("!right2!") do (
                if not %%W == !right2! (
                    echo.%%W
                )
            )
        )
    )
)
  • setlocal enabledelayedexpansion让您在循环中智能地处理变量。
  • for /f "tokens=*" %%L in (input.txt)input.txt每次读取一行并将每行放入索引变量中%%L
  • set line=%%L将文本复制到常规变量中,这样更易​​于操作。
  • set right1=!line:*testid=! 使用在变量扩展中执行字符串替换的语法(为了清楚起见添加了空格)。% var : str1 = str2 %

    • 由于扩展延迟,因此使用!而不是。%
    • var显然是line
    • str1*testid。 是通配符(模式匹配符号),因此它将匹配中 *第一次出现的 之前的所有内容。请注意,虽然我们希望testidlinestr1*testid=但不幸的是,这是不可能的str1包含=,因为=是之间的分隔符str1和 str2
    • str2一片空白。

    testid因此,这会将中 第一次出现的 之前的所有内容替换line为 null,并返回 之后的所有内容testid

  • 如果该行不包含testid,则上述代码将返回整个line,不变。因此,如果lineequals right1,则该行中没有testid。如果它们不同,则继续分析此行。
  • set left=!right1:~0,1!从 中提取第一个(最左边的)字符right1
  • if "!left!" == "=",后面的第一个字符testid=,所以我们找到了testid=,我们想继续分析该行。
  • set right2=!right1:~1!设置right2为除第一个字符之外的所有内容right1 ;即在 之后 =
  • for /f "tokens=1 delims=]" %%W in ("!right2!")right2]将 前面 的 文字拆分,]放入%%W.
  • 如果,则行中%%W == !right2!没有。]
  • 如果我们发现testid=],那么%%W就是它们之间的文本。您可能应该将其分配给常规变量。

披露:鉴于

[testid=a] and [testid=b]

此批处理文件将a仅查找;它不会查找b。鉴于行

[testid<c] and [testid=d]

批处理文件将找不到任何内容;第一个文件testid将其丢弃。

相关内容