2012-03-08 75 views
0

我正在使用的模擬程序需要基於文本的輸入文件。我需要通過更改文本文件中的值來以不同配置運行模擬。我正在尋找一種方法來使用任何不需要第三方編譯器的腳本自動執行此操作。它必須在Windows XP機器上本地運行。我在MATLAB和FORTRAN中只有一點編碼經驗。Windows原生腳本根據行號和列號更改文本文件

我將描述我的腳本應該在一些僞代碼做些什麼的想法:

% speed.txt - a txt file with 10 different speed values 
% coeff.txt - a txt file with 10 different coefficients 
% dist.txt - a txt file with 5 different distance values 
% input.txt - the txt file containing the input parameters. This file has to be changed. 
% output.txt- the output of the simulation 
% sp - the i-th speed value 
% co - the i-th coeff value 
% di - the j-th distance value 
% D:\FO - Final Output folder 

Read input.txt 
for i = 1:10 
    Display i on screen % so I know how much of the batch is done 
    Go to line 37, overwrite 1st four characters with i-th value from speed.txt 
    Go to line 68, overwrite 1st eight characters with i-th value from coeff.txt 
    for j = 1:5 
     Display j on screen % so I know how much of the batch is done 
     Go to line 67, overwrite 1st five characters with j-th value from dist.txt 
     Run simulation.exe 
     When simulation is done, get output.txt, rename it to "output_sp_co_di.txt" 
     and move the file to D:\FO 
    end 
end 

我希望這是可能的一個.bat或.vbs腳本(或其他任何將本機運行)。所有的幫助非常感謝。


編輯:經過一些建議,我開始一個VBS腳本。我從來沒有使用過這種語言,但是從廢料拉到這裏的東西一起下在互聯網上:

Option Explicit 

Dim objFSO, strTextFile, strData, strLine, arrLines 
Dim filesys, filetxt, path 
Dim speed(10), ct(10), dist(4), text(73), d(4) 
Dim i, j, k 
i = 0 
j = 0 
k = 0 

speed(0) = 3.0 
speed(1) = 5.0 
speed(2) = 7.0 
speed(3) = 9.0 
speed(4) = 11.0 
speed(5) = 13.0 
speed(6) = 15.0 
speed(7) = 17.0 
speed(8) = 19.0 
speed(9)= 21.0 
speed(10)= 22.0 

ct(0) = 0.987433 
ct(1) = 0.816257 
ct(2) = 0.816361 
ct(3) = 0.720357 
ct(4) = 0.418192 
ct(5) = 0.239146 
ct(6) = 0.154534 
ct(7) = 0.107608 
ct(8) = 0.079057 
ct(9)= 0.060437 
ct(10)= 0.053465 

dist(0) = 173.48 
dist(1) = 260.22 
dist(2) = 346.96 
dist(3) = 433.7 
dist(4) = 520.44 

d(0) = 2 
d(1) = 3 
d(2) = 4 
d(3) = 5 
d(4) = 6 


CONST ForReading = 1 

'name of the text file 
strTextFile = "TurbSim.inp" 

'Create a File System Object 
Set objFSO = CreateObject("Scripting.FileSystemObject") 


'Open the text file - strData now contains the whole file 
strData = objFSO.OpenTextFile(strTextFile,ForReading).ReadAll 

'Split the text file into lines 
arrLines = Split(strData,vbCrLf) 

'Step through the lines 
For Each strLine in arrLines 
    text(i) = strLine 
    i = i + 1 
Next 

'Open text file to write to 
path = objFSO.GetAbsolutePathName("D:\Sandbox\TurbSim.inp") 

For i = 0 To 10 
    If i = 0 Then 
     text(37) = Replace(text(37),"UUUU",speed(i)) 
     text(68) = Replace(text(68),"CCCCCCCC",ct(i)) 
    Else 
     text(37) = Replace(text(37),speed(i-1),speed(i)) 
     text(68) = Replace(text(68),ct(i-1),ct(i)) 
    End If 
    For j = 0 To 4 
     If j = 0 Then 
      text(67) = Replace(text(67),"DDDDD",dist(j)) 
     Else 
      text(67) = Replace(text(67),dist(j-1),dist(j)) 
     End If 

     Set filetxt = objFSO.opentextfile("D:\Sandbox\TurbSim.inp", 2, True) 
     For k = 0 To 73 
      if k = 73 Then 
       filetxt.write text(k) 
      Else 
       filetxt.write text(k) & vbCr & vbLf 
      End If 
      objFSO.CopyFile "D:\Sandbox\TurbSim.inp", _ 
      "D:\Sandbox\input\TurbSim_" & speed(i) & "_" & d(j) &"D.inp" 
     Next 
     filetxt.close 
    Next 
Next  


' wscript.echo text(37) 
' wscript.echo text(68) 
' wscript.echo text(67) 

filetxt.Close 
'Cleanup 
' Set filesys = Nothing 
Set objFSO = Nothing 

問題是,現在的距離部分(j-循環)工作不正常。從生成的輸出(TurbSim_speed_dD.inp)我看到只有最後一個距離(520.44)被使用。我不明白爲什麼,我會在稍後看看。如果任何人有改進的建議,那麼你總是受歡迎的想法。

+0

爲什麼你不開始寫一個批處理文件?用'for/L %% i替換僞'for i = 1:10'(1,1,10)do(' – jeb 2012-03-08 07:32:33

+0

我沒有開始批處理文件,因爲我不知道它是否有能力做我的同事給了我使用vbs文件的建議,因爲它們更加靈活,我在某個地方,但是有一些問題我會在後面發佈。 – 2012-03-08 09:34:27

回答

0

我已經成功地將各種互聯網參考文獻中的.vbs腳本放在一起,這些腳本都是我想要的。腳本執行以下操作:

  1. 讀入原始輸入文件
  2. 存儲所述數據線通過線文本陣列
  3. 在速度,係數和距離數據讀取從文本文件
  4. 將該數據存儲在以單獨的速度,係數和距離陣列逐行。
  5. 第一次輸入速度和coeff。陣列和 文本陣列中的適當的地方將其寫
  6. 循環通過距離陣列和由線寫入文本陣列線回到一個.INP文件
  7. 運行於所編輯的輸入文件
  8. 等待直到模擬仿真終止。
  9. 將輸出文件從當前目錄複製到輸出文件夾,並在進程中重命名它們。
  10. 等待10秒鐘以確保複印完成 10.用所有其他速度和coeff條目重複步驟6-10。這個腳本陣列

要求的工作:

A.與具有「UUUU」的.INP文件的輸入文件夾,「DDDDD」,「CCCCCCCC」寫在地方,分別是速度,距離並寫出係數。

B.輸出文件夾

C.這些文件speed.txt,ct.txt和包含速度,係數和距離值distance.txt使用。 D.您應該從管理員帳戶運行此腳本。否則,您無權檢查仿真是否仍在使用「Win32_process」運行。

Option Explicit 

Dim objFSO, strTextFile, strTData, strLine, arrTLines 
Dim strVelFile, strCtFile, strDistFile 
Dim strVData, strCData, strDData 
Dim arrVLines, arrCLines, arrDLines 
Dim strLineV, strLineC, strLineD 
Dim strComputer, oWMI, colEvents, oEvent 
Dim filesys, filetxt, path, curPath 
Dim speed(), ct(), dist(), text(73) 
Dim oShell 
Dim i, j, k 
i = 0 
j = 0 
k = 0 

' Subroutine to start an executable 
Sub Run(ByVal sFile) 
Dim shell 

    Set shell = CreateObject("WScript.Shell") 
    shell.Run Chr(34) & sFile & Chr(34), 1, false 
    Set shell = Nothing 
End Sub 

CONST ForReading = 1 

' Create a File System Object 
Set objFSO = CreateObject("Scripting.FileSystemObject") 

' Create Shell object. Needed to change directories 
Set oShell = CreateObject("WScript.Shell") 

'Change current directory to \input folder 
oShell.CurrentDirectory = ".\input" 

' The name of the original input file 
' with the UUUU, DDDDD, CCCCCCC in the correct places 
strTextFile = "TurbSim.inp" 

' Open the text file and read it all into strTData 
strTData = objFSO.OpenTextFile(strTextFile,ForReading).ReadAll 

' Go back to parent folder as there all the other .txt files reside 
Set oShell = CreateObject("WScript.Shell") 
oShell.CurrentDirectory = ".\.." 

' name of other input text files 
strVelFile = "speed.txt" 
strCtFile = "ct.txt" 
strDistFile = "dist.txt" 

' Open the text file - str*Data now contains the whole file 
strVData = objFSO.OpenTextFile(strVelFile,ForReading).ReadAll 
strCData = objFSO.OpenTextFile(strCtFile,ForReading).ReadAll 
strDData = objFSO.OpenTextFile(strDistFile,ForReading).ReadAll 

' Split the text files into lines 
arrTLines = Split(strTData,vbCrLf) 
arrVLines = Split(strVData,vbCrLf) 
arrCLines = Split(strCData,vbCrLf) 
arrDLines = Split(strDData,vbCrLf) 

' Give the speed, ct and dist arrays their dimension 
ReDim speed(UBound(arrVLines)) 
ReDim ct(UBound(arrCLines)) 
ReDim dist(UBound(arrDLines)) 

' Add data to arrays text, speed, ct and dist line by line 
For Each strLine in arrTLines 
    text(i) = strLine 
    i = i + 1 
Next 

'Reset counter 
i = 0 

' Step through the lines speed 
For Each strLineV in arrVLines 
    speed(i) = strLineV 
    i = i + 1 
Next 
i = 0 
' Step through the lines ct 
For Each strLineC in arrCLines 
    ct(i) = strLineC 
    i = i + 1 
Next 
i = 0 
' Step through the lines dist 
For Each strLineD in arrDLines 
    dist(i) = strLineD 
    i = i + 1 
Next 
i = 0 

' Get the current path. Needed to point to the executable. 
curPath = objFSO.GetAbsolutePathName(".") 

For i = 0 To UBound(speed) 
    If i = 0 Then 
     ' Replace the UUUU and CCCCCCCC values 
     ' Only the first run.  
     text(37) = Replace(text(37),"UUUU",speed(i)) 
     text(68) = Replace(text(68),"CCCCCCCC",ct(i)) 
    Else ' Replace the previous speed and coeff. values with the current one 
     text(37) = Replace(text(37),speed(i-1),speed(i)) 
     text(68) = Replace(text(68),ct(i-1),ct(i)) 
    End If 
    For j = 0 To UBound(dist) 
     If j = 0 And i = 0 Then 
      ' Replace the DDDDD value (only at first run) 
      text(67) = Replace(text(67),"DDDDD",dist(j)) 
     ElseIf j = 0 And i > 0 Then 
      ' Replace the distance value of the previous speed/coeff. case 
      ' with the current one 
      text(67) = Replace(text(67), dist(UBound(dist)), dist(j)) 
     Else ' Replace the previous distance value with the current one 
      text(67) = Replace(text(67),dist(j-1),dist(j)) 
     End If 
     Set filetxt = objFSO.opentextfile(curPath & "\TurbSim.inp", 2, True) 
     For k = 0 To 73 ' Write to an .inp file line by line 
      if k = 73 Then ' Prevent adding a new line at the end 
       filetxt.write text(k) 
      Else 
       filetxt.write text(k) & vbCr & vbLf 
      End If 
     Next 
     filetxt.close 
     ' Execute the simulation 
     Run curPath &"\TurbSimGW.exe" 

     strComputer = "." 
     Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 

     '# Create an event query to be notified within 3 seconds when TurbSimGW is closed 
     Set colEvents = oWMI.ExecNotificationQuery _ 
      ("SELECT * FROM __InstanceDeletionEvent WITHIN 3 " _ 
      & "WHERE TargetInstance ISA 'Win32_Process' " _ 
      & "AND TargetInstance.Name = 'TurbSimGW.exe'") 

     '# Wait until TurbSimGW is closed 
     Set oEvent = colEvents.NextEvent 

     ' Copy and rename output files 
     objFSO.CopyFile curPath & "\TurbSim.wnd", _ 
     curPath & "\output\TurbSim_" & speed(i) & "_" & j+2 &"D.wnd" 
     wscript.sleep 10000 ' time to allow copying the files 
    Next 
Next  


'' ' wscript.echo text(37) 
'' ' wscript.echo text(68) 
'' ' wscript.echo text(67) 

filetxt.Close 
' Cleanup 
' Set filesys = Nothing 
Set objFSO = Nothing 

現在它的工作完美無瑕。然而,要求D的解決方案會很好。我的解決方法是,而不是檢查程序是否被終止,我只是設置一個睡眠值。對於這個睡眠值,我知道模擬已經完成,輸出文件已準備好複製。

+0

在一個批處理文件中,任何命令的執行都會實現,直到前一個命令結束爲止,所以這個檢查甚至不需要:) – Aacini 2012-03-10 04:00:25

2

下面的批處理文件是您的VBS腳本的蝙蝠版本:

@echo off 
SetLocal EnableDelayedExpansion 

REM Auxiliary macro for easier replacements 
set Replace=for /F "tokens=1,2 delims==" %%x in 

:: speed - vector with 11 different speed values 
Set i=0 
For %%s in (3.0 5.0 7.0 9.0 11.0 13.0 15.0 17.0 19.0 21.0 22.0) do (
    Set speed[!i!]=%%s 
    Set /A i+=1 
) 

:: ct - vector with 11 different coefficients 
Set i=0 
For %%c in (0.987433 0.816257 0.816361 0.720357 0.418192 0.239146 0.154534 0.107608 0.079057 0.060437 0.053465) do (
    Set ct[!i!]=%%c 
    Set /A i+=1 
) 

:: dist - vector with 5 different distance values 
Set i=0 
For %%d in (173.48 260.22 346.96 433.7 520.44) do (
    Set dist[!i!]=%%d 
    Set /A i+=1 
) 

REM d does not need to be a vector because d(i) = i+2 

:: Split the text file into lines, and Step through the lines 
Set i=0 
For /F "delims=" %%l in (TurbSim.inp) do (
    Set "text[!i!]=%%l" 
    Set /A i=i+1 
) 

For /L %%i in (0,1,10) do (
    If %%i == 0 (
     %Replace% ("UUUU=!speed[%%i]!") do set "text[37]=!text[37]:%%x=%%y!" 
     %Replace% ("CCCCCCCC=!ct[%%i]!") do set "text[68]=!text[68]:%%x=%%y!" 
    ) Else (
     set /A iM1=i-1 
     %Replace% ("!iM1!") do set speed_iM1=!speed[%%x]!& set ct_iM1=!ct[%%x]! 
     %Replace% ("!speed_iM1!=!speed[%%i]!") do set "text[37]=!text[37]:%%x=%%y!" 
     %Replace% ("!ct_iM1!=!ct[%%i]!") do set "text[68]=!text[68]:%%x=%%y!" 
    ) 
    For /L %%j in (0,1,4) do (
     If %%j == 0 (
      %Replace% ("DDDDD=!dist[%%j]!") do set "text[67]=!text[67]:%%x=%%y!" 
     ) Else (
      set /A jM1=j-1 
      %Replace% ("!jM1!") do set dist_jM1=!dist[%%x]! 
      %Replace% ("!dist_jM1!=!dist[%%j]!") do set "text[67]=!text[67]:%%x=%%y!" 
     ) 
     set /A d=j+2 
     (For /L %%k in (0,1,73) do (
      if %%k == 73 (
       set /P =!text[%%k]!< NUL 
      ) Else (
       echo !text[%%k]! 
      ) 
     )) > "D:\Sandbox\input\TurbSim_!speed[%%i]!_!d!D.inp" 
    ) 
) 


echo %text[37]% 
echo %text[68]% 
echo %text[67]% 

注:

1 - 這是基於你的vbs腳本第一次嘗試批處理文件;我真的不明白你想要做什麼,只是做了一個直接的翻譯。看來您在問題中提出的要求與vbs腳本不同。如果你給我具體的細節,任何問題都可以解決。

2-上一個批處理文件從輸入文件中刪除任何空行。如有需要可以解決這個問題。

3-批量文本替換爲文本,不是數值。任何數字必須寫作完全相同的作爲數組值以便被替換。我認爲同樣的行爲適用於vbs。

4-輸入文件不能包含某些特殊的批處理字符,如! ^和其他人。這可能只在某些情況下得到解決。

+0

非常感謝你的努力,但只是幾分鐘以前我設法讓我的vbs文件工作,我會在這裏發佈以供進一步參考 – 2012-03-09 05:52:09

+0

經過一段時間的思考,我現在明白了爲什麼你不明白我想要做什麼,我首先發布的vbs代碼不會做我要求的最初是因爲它只是一個部分代碼,我還沒有完成它,當我離開我的工作時,我在這裏發佈它來表明我正在處理它,我發佈的部分只是輸入文件修改。我已經發布了完整的vbs代碼,按照我在第一篇文章中的要求工作。謝謝y ou再次爲你的努力和遺憾,我給了不清楚的信息。 – 2012-03-09 06:39:41