![使用批次腳本解析字串](https://rvso.com/image/1449110/%E4%BD%BF%E7%94%A8%E6%89%B9%E6%AC%A1%E8%85%B3%E6%9C%AC%E8%A7%A3%E6%9E%90%E5%AD%97%E4%B8%B2.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
邏輯中的主要問題之一是,如果某件事為真,則設定「導入」變數一次,但永遠不會重置它,或者如果不再為真,則取消定義它。因此,在第一次設定後,它將在循環的其餘部分保持「已定義」狀態。
我的偏好是專門設定變數(true
或false
)。將其設為false
啟動,然後true
根據需要將其設為,但請確保false
在需要時將其設定回。然後,在循環的每次迭代中檢查變數是否被專門設定為True
orFalse
而不是檢查它是否剛剛定義。
根據您的資訊/目標,此程式碼對我有用:
@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
)
)
)
)
我們特意將「導入」變數(標誌)設定為false
啟動。
第一個 For 迴圈遍歷檔案中的每一行(test.txt
在本例中,由「buildlog」變數指定;注意:您需要刪除變數中檔案名稱周圍的引號,以便它在 For 迴圈中運作) 。
第一個 IF 查看目前行是否為「Import:」行,如果是,則將「import」標誌翻轉為true
。
下一個 IF 查看目前行是否為「View:」行,如果是,則將「import」標誌翻轉(返回)為false
,以便停止處理每一行。
第三個 IF 檢查「導入」標誌是否為true
,如果是,則處理該行。
如果是true
,則巢狀(第四個)IF 檢查該行是否為實際的「import:」行,如果不是,則顯示該行(防止它在輸出中顯示「Import:」行)。
第二個 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
解析器.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