我正在使用的模拟程序需要基于文本的输入文件。我需要通过更改文本文件中的值来运行不同配置的模拟。我正在寻找一种方法来自动执行任何不需要第三方编译器的脚本。它必须在Windows XP计算机上本机运行。我在MATLAB和FORTRAN中只有一点编码经验。
我将描述我在一些伪代码中应该做什么的想法:
% 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脚本(或其他任何本机运行的脚本)都可以实现这一点。非常感谢所有帮助。
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 :(得分:2)
下面的批处理文件是vbs脚本的.bat版本:
@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-批处理中的文本替换是 textual ,而不是数值。任何数字必须与数组值完全相同才能被替换。我认为同样的行为适用于vbs。
4-输入文件不得包含某些特殊的批处理字符,如! ^和其他人。这可能仅在某些情况下得到修复。
答案 1 :(得分:0)
我已经成功地从各种互联网引用中提取了一个.vbs脚本,它可以实现我想要的功能。该脚本执行以下操作:
此脚本的要求:
一个。一个带有.inp文件的输入文件夹,其中“UUUU”,“DDDDD”,“CCCCCCCC”写在应分别写入速度,距离和系数的地方。
B中。输出文件夹
℃。文件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要求的解决方案会很好。我的解决方法是检查程序是否终止,而不是检查程序是否设置了睡眠值。对于这个睡眠值,我确信模拟已完成,输出文件已准备好复制。