要解决您的任务,您必须解决一些子问题:
- VBScript 中的字符串连接:
"... exe " vmd5 & " "
- 要拼接变量 vmd5 的内容,您需要两侧的连接运算符 - 但这是您想要做的吗?" " & C:\Testscripts\
- 要附加文字'C:\Testscripts\',您需要(双)引用文字 - 但是您可以将所有组件组合成一个字符串文字。
- 在 VBScript 中 " 用作字符串文字分隔符;它们不像更强大的脚本语言中的反引号那样工作。md5Command必须包含您要执行的命令;要获得该命令的结果是另一回事。
- 要脱壳/执行命令,您必须使用 WScript.Shell 对象的 .Exec 或 .Run 方法并收集输出。
- 根据您使用的工具(输出),您将无法通过 = 运算符比较结果 - 例如,文件/校验和的路径或顺序可能不同。因此,您需要一种策略来解析捕获的输出。
你想先处理哪个子问题?
正如您的评论所证明的,正确的语法应该是起点。这个:
Dim aDirs : aDirs = Array("..\data\one", "..\data\two")
' Join an array of the components (no more problems
' with (forgetting (to concat)) separators)
' Use qq() function to lessen the noise
Dim sCmdT : sCmdT = Join(Array( _
"fciv" _
, "-add" _
, qq("§DIR§") _
), " ")
Dim nDir, sDir, sCmd
For nDir = 0 To UBound(aDirs)
sDir = aDirs(nDir)
' Use replace on a template to avoid repetition
sCmd = Replace(sCmdT, "§DIR§", sDir)
WScript.Echo "sCmd: |" & sCmd & "|"
Next
输出:
sCmd: |fciv -add "..\data\one"|
sCmd: |fciv -add "..\data\two"|
说明了 3 种方法,使“构建”(shell)命令或 SQL 语句更容易/更不容易出错。(qq() 函数的实现留作练习)。
由于我没有 vmd5 实用程序,我将在进一步的示例中使用 fciv。
下一个(版本的)脚本:
Dim aDirs : aDirs = Array("..\data\one", "..\data\two")
Dim sCmdT : sCmdT = Join(Array( _
"fciv" _
, "-add" _
, qq("§DIR§") _
), " ")
Dim oWSH : Set oWSH = CreateObject("WScript.Shell")
Dim nDir, sDir, sCmd, oExec, sRes
For nDir = 0 To UBound(aDirs)
sDir = aDirs(nDir)
sCmd = Replace(sCmdT, "§DIR§", sDir)
Set oExec = oWSH.Exec(sCmd)
sRes = oExec.Stdout.ReadAll()
WScript.Echo sRes
Next
输出:
CmpMd500 - compare md5 checksums
==============================================================
//
// File Checksum Integrity Verifier version 2.05.
//
09fea378b96141413f5f09444573f0f3 ..\data\one\version.txt
4945c1ffd9ceb14c83e003091c6e8455 ..\data\one\README.md
4c4c34f7b6f0863056615d2cbcdf6912 ..\data\one\History.txt
//
// File Checksum Integrity Verifier version 2.05.
//
09fea378b96141413f5f09444573f0f3 ..\data\two\version.txt
4945c1ffd9ceb14c83e003091c6e8455 ..\data\two\README.md
4c4c34f7b6f0863056615d2cbcdf6912 ..\data\two\History.txt
==============================================================
演示了执行命令和捕获输出的绝对最少代码 - 生产版本必须添加大量代码以进行错误处理。同时,它显示了示例输出以讨论如何解析/比较校验和。您可以发布 vmd5 实用程序的示例输出吗?
无论您是直接获得 md5 实用程序的输出(我上面的示例)还是从文件中获得输出,您都需要一个正则表达式来将字符串解析为可以进一步处理的数据。一个简单的脚本来处理您在问题中发布的文件:
Dim reMd5File : Set reMd5File = New RegExp
reMd5File.Global = True
reMd5File.Multiline = True
reMd5File.Pattern = "^(\S+)\s+(\w{32})"
Dim sDir : sDir = "..\data\three"
Dim oFile
For Each oFile In goFS.GetFolder(sDir).Files
Dim sAll : sAll = oFile.OpenAsTextStream(ForReading).ReadAll()
WScript.Echo sAll
Dim oMTS : Set oMTS = reMd5File.Execute(sAll)
Dim oMT
For Each oMT In oMTS
WScript.Echo "** parsed:", qq(oMT.Submatches(1)), qq(oMT.Submatches(0))
Next
Next
输出:
CmpMd501 - compare md5 checksums
==================================================================
Vallen VMD5 R2009.1215
Filename MD5 sum
------------------------------------------------------------
[C:\ScriptOutput\]
Testzip.zip d5db2ff8c372a12c145170fb7340e682
version.txt 09fea378b96141413f5f09444573f0f3
README.md 4945c1ffd9ceb14c83e003091c6e8455
History.txt 4c4c34f7b6f0863056615d2cbcdf6912
** parsed: "d5db2ff8c372a12c145170fb7340e682" "Testzip.zip"
** parsed: "09fea378b96141413f5f09444573f0f3" "version.txt"
** parsed: "4945c1ffd9ceb14c83e003091c6e8455" "README.md"
** parsed: "4c4c34f7b6f0863056615d2cbcdf6912" "History.txt"
********************
Vallen VMD5 R2009.1215
Filename MD5 sum
------------------------------------------------------------
[C:\ScriptOutput\]
Testzip.zip d5db2ff8c372a12c145170fb7340e682
** parsed: "d5db2ff8c372a12c145170fb7340e682" "Testzip.zip"
********************
==================================================================
xpl.vbs: Erfolgreich beendet. (0) [0.14844 secs]
通过该代码工作后,您将对此脚本没有任何问题,它将“将结果存储在字典中”添加到我的“读取 .Exec 输出”版本中:
Dim aDirs : aDirs = Array("..\data\one", "..\data\two")
Dim sCmdT : sCmdT = Join(Array( _
"fciv" _
, "-add" _
, qq("§DIR§") _
), " ")
Dim oWSH : Set oWSH = CreateObject("WScript.Shell")
ReDim aRes(UBound(aDirs))
Dim reMd5File : Set reMd5File = New RegExp
reMd5File.Global = True
reMd5File.Multiline = True
reMd5File.Pattern = "^(\w{32})\s(.+?)\s+$"
Dim nDir, sDir, sCmd, oExec, sRes, oMTS, oMT
For nDir = 0 To UBound(aDirs)
sDir = aDirs(nDir)
sCmd = Replace(sCmdT, "§DIR§", sDir)
Set oExec = oWSH.Exec(sCmd)
sRes = oExec.Stdout.ReadAll()
Set aRes(nDir) = CreateObject("Scripting.Dictionary")
Set oMTS = reMd5File.Execute(sRes)
For Each oMT in oMTS
aRes(nDir)(goFS.GetBaseName(oMT.SubMatches(1))) = oMT.SubMatches(0)
Next
Next
Dim sFile
For nDir = 0 To UBound(aDirs)
For Each sFile In aRes(nDir).Keys
WScript.Echo aRes(nDir)(sFile), sFile
Next
WScript.Echo
Next
输出:
===========================================
09fea378b96141413f5f09444573f0f3 version
4945c1ffd9ceb14c83e003091c6e8455 README
0252535193507019a0eb97328d28dd80 robic
4c4c34f7b6f0863056615d2cbcdf6912 History
09fea378b96141413f5f09444573f0f3 version
4945c1ffd9ceb14c83e003091c6e8455 README
4c4c34f7b6f0863056615d2cbcdf6912 History
c46264f8101b6c1609c77b4c674bd327 Rakefile
===========================================
下一步——也是最后一步,我希望——进行比较(一个文件夹中是否缺少文件?,“相同”文件的校验和是否不同?)。你有什么想法吗?