バッチスクリプトを使用して文字列を解析する

バッチスクリプトを使用して文字列を解析する

バッチ スクリプトを使用して文字列を解析するにはどうすればよいですか?

目標は、配列に以下のすべてを保存し、たとえば -->およびImport:を削除することです。#head//MPackages/Project/config/abc.txt//Packages/Project/config/cde.txt

テスト.txt:

Version: 4.5.0
Import:
   //MPackages/Project/config/abc.txt                       #head
   //Packages/Project/config/cde.txt                        #head
View:
  //MPackages/Project/config/ac.txt                     #head
  //Packages/Project/config/de.txt                      #head

私の試み:

@echo off

set buildlog="devel.p4inc"

setlocal EnableDelayedExpansion
for /F "tokens=*" %%A in  (devel.p4inc) do  (
  if /i "%%A"=="Import:" set "import=true"
  IF DEFINED import (echo %%A)
)

望ましい出力

   //MPackages/Project/config/abc.txt 
   //Packages/Project/config/cde.txt

インポートの下にあるもの:

答え1

あなたのロジックの主な問題の 1 つは、何かが true の場合に「import」変数を一度設定しても、それが true でなくなった場合にそれをリセットしたり未定義にしたりしないことです。そのため、最初に設定した後は、ループの残りの間は「定義された」ままになります。

私の好みは、変数を具体的に (trueまたは)に設定することです。最初にfalseに設定し、必要に応じて に設定しますが、必要なときに に戻すことも忘れないでください。次に、ループの各反復で、変数が単に定義されているかどうかをチェックするのではなく、変数が具体的にまたはに設定されているかどうかをチェックします。falsetruefalseTrueFalse

このコードはあなたの情報/目標に基づいて私にとっては機能します:

@echo off

setlocal EnableDelayedExpansion

set buildlog=test.txt
set import=false

for /F "tokens=*" %%A in (%buildlog%) do (
    if /i "%%A"=="Import:" (
        set import=true
    )
    if /i "%%A"=="View:" (
        set import=false
    )
    if !import!==true (
        if not "%%A"=="Import:" (
            for /F "tokens=1" %%B in ("%%A") do (
                echo %%B
            )
        )
    )
)

開始するには、意図的に「Import」変数(フラグ)を に設定しますfalse

最初の For ループは、ファイル内の各行を処理します (test.txtこの例では、「buildlog」変数で指定されています。注意: For ループで動作させるには、変数内のファイル名を囲む引用符を削除する必要があります)。

最初の IF は、現在の行が「Import:」行であるかどうかを確認し、そうである場合は、「import」フラグを に切り替えますtrue

次の IF は、現在の行が「View:」行であるかどうかを確認し、そうである場合は、「import」フラグを に反転して ( に戻して) false、各行の処理を停止します。

3 番目の IF は、「インポート」フラグが であるかどうかを確認しtrue、そうである場合は行を処理します。

そうである場合true、ネストされた (4 番目の) IF は、その行が実際の「import:」行であるかどうかを確認し、そうでない場合はその行を表示します (出力に「Import:」行が表示されないようにします)。

2 番目の For ループは、表示する行を通過し、 を除外して、必要なパスである最初のトークン セットのみを取得します#head

詳細/関連情報:

コメント後に編集:

「View:」行の後にバージョン番号がある場合、その行を処理するには、コードを次のように変更します。

@echo off

setlocal EnableDelayedExpansion

set buildlog=test.txt
set import=false

for /F "tokens=*" %%A in (%buildlog%) do (
    for /F "tokens=1" %%B in ("%%A") do (
        if /i "%%B"=="Import:" (
            set import=true
        )
        if /i "%%B"=="View:" (
            set import=false
        )
        if !import!==true (
            if not "%%B"=="Import:" (
                for /F "tokens=1" %%C in ("%%A") do (
                    echo %%C
                )
            )
        )
    )
)

この追加された For ループは、行全体をチェックする代わりに、行から最初のトークンを取得して、それが「View:」か「Import:」かをチェックします。チェックを行うために、行で最初に遭遇したスペースの後にあるものはすべて無視されます。

答え2

@echo off
for /F "usebackq tokens=1" %%A in  ("devel.p4inc") do  (
Set temp=False
if "%%A" == "View:" Goto Exit
if  not "%%A" == "Import:" if  not "%%A" == "Version:"  echo %%A
)
:Exit

答え3

コマンドライン:

powershell [string]$f=gc test.txt;$pL=$f.IndexOf('Import:')+7;$pR=$f.IndexOf('View:');$s=$f.Substring($pL,$pR-$pL);$s -split'#head'^|ac result.txt

パワーシェル:

powershell ./parsefl.ps1

パースfl.ps1

[string]$f=gc test.txt;
$pL=$f.IndexOf('Import:')+'Import:'.Length;$pR=$f.IndexOf('View:');
$s=$f.Substring($pL,$pR-$pL);
$s -split'#head'|ac result.txt

関連情報