2

我正在尝试比较一些文件的一些 Md5,看看它们在我将它们复制到另一个驱动器后是否相同,如果它们相同,则删除原始文件。我迷失在语法上,因为我以前从未做过这样的事情。

我正在使用免费实用程序 vmd5.exe(命令行)来获取 md5。我只是不确定如何告诉 vbscript 如果输出相同,那么继续删除文件。这只是我试图比较两个 md5 的部分的一个片段,但这是我到目前为止所拥有的:

Dim md5Command, md5Command2

md5Command = "C:\Program Files\vmd5.exe " vmd5 & " " & C:\Testscripts\ 
md5Command2 = "C:\Program Files\vmd5.exe " vmd5 & " " & E:\CopyTestFolder\

If md5Command = md5Command2 then 

objFSO.DeleteFolder("C:\ScriptOutput") 'Can either delete entire archived folder, or just .zip files in folder


objFSO.DeleteFile("C:\Testscripts\Archive*.evtx") 'This will be path where archived logs are located once finished

Else 

End If

这种语法肯定是错误的。但是根据我对 IF 的了解,我需要它看起来像这样。我只是不确定是否需要告诉脚本运行“设置”部分中的命令,或者我如何告诉脚本从命令行获取 md5 输出并将其与另一个进行比较。

在 Else 语句之后,我希望它要么结束脚本,要么只输出具有不同 md5 的文本文件,但我还没有到那一点,还没有真正决定任何事情。

如果有更好的方法来做这样的事情,我也会这样做,不过这就是我今天早上想出的全部内容。

编辑:我想到了一些可能的事情。如果我告诉命令行将输出的内容输出到文本文件,那么我可以比较两个不同的文本文件,如果内容匹配,那么它可以继续执行脚本的其余部分。我不知道如何让它工作,但逻辑似乎是有道理的。

以下是它创建的文本文件的输出:

Vallen VMD5 R2009.1215

Filename                               MD5 sum
------------------------------------------------------------
[C:\ScriptOutput\]
Testzip.zip                     d5db2ff8c372a12c145170fb7340e682
4

1 回答 1

1

要解决您的任务,您必须解决一些子问题:

  1. VBScript 中的字符串连接:"... exe " vmd5 & " "- 要拼接变量 vmd5 的内容,您需要两侧的连接运算符 - 但这是您想要做的吗?" " & C:\Testscripts\- 要附加文字'C:\Testscripts\',您需要(双)引用文字 - 但是您可以将所有组件组合成一个字符串文字。
  2. 在 VBScript 中 " 用作字符串文字分隔符;它们不像更强大的脚本语言中的反引号那样工作。md5Command必须包含您要执行的命令;要获得该命令的结果是另一回事。
  3. 要脱壳/执行命令,您必须使用 WScript.Shell 对象的 .Exec 或 .Run 方法并收集输出。
  4. 根据您使用的工具(输出),您将无法通过 = 运算符比较结果 - 例如,文件/校验和的路径或顺序可能不同。因此,您需要一种策略来解析捕获的输出。

你想先处理哪个子问题?

正如您的评论所证明的,正确的语法应该是起点。这个:

  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

===========================================

下一步——也是最后一步,我希望——进行比较(一个文件夹中是否缺少文件?,“相同”文件的校验和是否不同?)。你有什么想法吗?

于 2012-07-11T15:22:58.843 回答