如何透過批次腳本提取兩個特定字串之間的行的一部分

如何透過批次腳本提取兩個特定字串之間的行的一部分

我正在嘗試提取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 中的正規表示式透過批次檔來完成此操作:

@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。是 *一個通配符(模式匹配符號),因此這將匹配第一次出現testidin 之前的所有內容line。請注意,雖然我們希望str1*testid=,但不幸的是,這是不可能的str1包含=,因為=是 之間的分隔符str1和 str2
    • str2一片空白。

    testid因此,這會將第一次出現in 之前的所有內容替換line為 null,並傳回 後的所有內容testid

  • 如果該行不包含testid,則上面的內容將傳回整個line,保持不變。因此,如果line等於,則該行中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把它丟掉了。

相關內容