我有一個文本文件,它使用[]對不同的子系統進行分組,然後在每個子組中包含項目標誌。下面是該文件的一個片段,這樣你可以得到它是什麼樣的理解(注意,每個小組可以有相同的項目):.bat文件搜索和替換結構化文本文件中的字符串
[EV]
Verbosity=0
Alignment=123
[FluidLevelControl]
BufferTypeLastUsed=TWEEN
Enable Dip Tube=no
Alignment=456,efg
[PressureLevelControl]
Enabled=yes
Alignment=789,abc
Calibration Date=1280919634
[BufferFrontValve]
Log=yes
Alignment=987
注意,上述文件是超過2000行。我想這個腳本會花一點時間來執行。我也知道有一個更好的框架來做到這一點,但在我們的應用程序,我們需要它從閃存驅動器運行,並能夠插入我們的儀器運行WinXP沒有.NET框架等
我什麼想要做的就是使用.bat文件在文檔中搜索特定子系統(即[DesiredSubsystem])和子系統中的所需項目,然後修改項目數據。例如,在上面的文本中,我可能想要將PressureLevelControl子組中的對齊從789更改爲12345。
我知道沒有辦法使用bat文件有效地替換/更新文本文件。我創建了一個函數來讀取文件並將其寫入新文件,現在我正在嘗試開發一種乾淨的方式來識別行項目以及它們所在的子組,以根據需要替換所需的文本。
以下是我與我的計劃說: 更新:我花了一個下午寫一些代碼,似乎工作,如下圖所示,有最清晰度更好的方法。
::SET VARS
set "varDebugFP=\\svchafile\Teams\Test Engineering\Productivity Tools\MFG BAT Files\SpecificTest\"
set varSource=%varDebugFP%Debug\
set varDestination=%varDebugFP%Debug\
set varFileName=specific.ini
::Do Text File Editing
setlocal enableDelayedExpansion
set "LastGroup=NONE"
::preserve blank lines using FINDSTR, even if a line may start with :
for /f "usebackq delims=*" %%A in (`type "%srcFile%" ^| findstr /n "^"`) do (
set "strLine=%%A"
set "strLine=!strLine:*:=!"
::Check to see if the is defined and greater than 2 characters inidicating a good line
if defined strLine if NOT "!strLine:~2,1!"=="" if "!strLine:~0,1!!strLine:~-1!"=="[]" (set "LastGroup=!strLine!")
::Set the paramaters looking to match
set "DesiredGroup=[TestGroup]"
set "DesiredItem=TestItem"
set "ReplaceLineWith=NewTestItemLine=NewData"
::Look for match on current line
if defined strLine if "!LastGroup!"=="!DesiredGroup!" if NOT "!strLine!"=="!strLine:TestItem=Mod!" (set "strLine=!ReplaceLineWith!")
::Note, in the above line I would like 'TestItem' to be the 'DesiredItem' variable but I can't get it working due to the DelayedExpansion
::Set the additonal paramaters looking to match
::Note, there are multiple items I want to change at once without having to reitterate through the org long (2000+lines) file
set "DesiredGroup=[TestGroup2]"
set "DesiredItem=TestItem2"
set "ReplaceLineWith=NewTestItemLine2=NewData2"
if defined strLine if "!LastGroup!"=="!DesiredGroup!" if NOT "!strLine!"=="!strLine:TestItem=Mod!" (set "strLine=!ReplaceLineWith!")
::I plan to copy and paste the above section as many times as needed to capture all the lines I need to edit (at this point about ~10)
::I don't really understand why the "(" in the below line, I found it in an example on stackoverflow and it seems to work.
echo(!strLine!>>"%newFile%"
)
endlocal
::Replace org file with new file, delete org file (this part I have figured out)
有沒有更好的方法來做到這一點?任何人都可以幫助完成代碼,因爲我有很多麻煩解決這個問題。
更新:感謝下面答案中提出的兩種方法。他們很長,我從他們身上學到了很多東西。不完全確定如何實現這些功能,但我最擔心的是使用該功能會使重複讀取文件的速度顯着降低。我對這個bat文件很陌生,但我知道它非常強大,如果你知道這些命令並且很有創意。
在此先感謝您的幫助。 -Dan
也許你可以考慮這篇文章:http://blogs.technet.com/b/deploymentguys/archive/2010/07/15/reading-and-modifying-ini-files-with-scripts.aspx –
這可能是我會爭辯爲正確工作使用正確工具的地方。我建議使用任何公開['GetPrivateProfileString'](http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms724353%28v=vs.85%29.aspx)函數系列的任何東西,因爲這是大多數程序使用的而不是從頭開始重現功能的。值得關注的腳本語言有[AutoIt](http://www.autoitscript.com/site/autoit/)。 – daalbert
dbenham的REPL.BAT解決方案在處理文件時比純批處理代碼更健壯,而且比簡單批處理代碼更快。它只讀取一次文件,因此請測試他的解決方案以仔細檢查功能。 – foxidrive