バッチ スクリプトを使用して、特定の 2 つの文字列の間にある行の一部を抽出する方法

バッチ スクリプトを使用して、特定の 2 つの文字列の間にある行の一部を抽出する方法

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= このバッチ ファイルは、行内のどこに出現するかに関係なく、各行の (最初の) (存在する場合) と (最初の) 後続の](存在する場合) の間のテキストを抽出しますが、私が特定できた 1 つの例外があります (回答の下部を参照)。

@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一度に 1 行ずつ読み取り、各行をインデックス変数に格納します%%L
  • set line=%%Lテキストを通常の変数にコピーするので、操作が簡単になります。
  • set right1=!line:*testid=!変数展開で文字列置換を行うための構文を 使用します(わかりやすくするためにスペースが追加されています)。% var : str1 = str2 %

    • 拡張が遅れるため、!の代わりにを使用します。%
    • var明らかにそうですline
    • str1*testidワイルド カード(パターンマッチングシンボル)なので、これはの *最初の出現まですべてに一致します。testidlinestr1です*testid=が、残念ながらそれは不可能ですstr1を含む=、なぜなら は=の間の区切り文字だからstr1そして str2
    • str2無効である。

    testidしたがって、これはの 最初の出現までのすべてをlinenull に置き換え、 以降のすべてを返します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はそれを破棄します。

関連情報