![バッチスクリプトを使用して文字列を解析する](https://rvso.com/image/1449110/%E3%83%90%E3%83%83%E3%83%81%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%99%E3%82%8B.png)
バッチ スクリプトを使用して文字列を解析するにはどうすればよいですか?
目標は、配列に以下のすべてを保存し、たとえば -->および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
に設定し、必要に応じて に設定しますが、必要なときに に戻すことも忘れないでください。次に、ループの各反復で、変数が単に定義されているかどうかをチェックするのではなく、変数が具体的にまたはに設定されているかどうかをチェックします。false
true
false
True
False
このコードはあなたの情報/目標に基づいて私にとっては機能します:
@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