比较文本文件 - 使用VBscripting标记一些文本

时间:2012-09-06 14:10:07

标签: vbscript compare text-files

首先,我不是编程背景,而是VBscript的新手。出于某些原因,我必须在办公室执行此脚本任务。 我想将它与Quick Test Professional 11一起使用。

我在其他论坛上也经历过很多帖子,但无法找到所需的信息。

好的,这就是我需要做的事情:

我必须比较两个文本文件并在第三个文件中写下差异。 这两个文件的某些字段的内容几乎相同,即:日期,订单号等等。

例如,File-1的日期为:00/11/1234,订单号为:1111,File-2的日期为:11/00/6789,订货号:2222 那么有什么办法可以忽略这些领域及其价值吗? 有没有办法可以创建我可以添加的忽略列表,哪些将在比较期间使用,并在比较期间跳过这些字段? 所以我的差异文件不会有这些差异,因为这些值总是不同的。 所以我可以在结果文件中获得所有其他差异。

供您参考,以下是示例文件。

到目前为止,我已经比较了两个文件,但最简单的方法是,我不知道如何忽略这些字段。 我想将这些任务作为一个函数,以便我可以在我的函数库中使用它。

文件-1

日期:00/11/1234 /订单号:1111

价格1:1111.00美元

价格2:2222.00美元

价格3:1234.00美元

ABC def GHI kjl 1111

订单号:1111

期限:2年

日期:00/11/1234

文件-2

日期:11/00/6789和订单号:2222

价格1:1111.00美元

价格2:2222.00美元

价格3:$ 5678.00

ABC def GHI kjl 1111

订单号:2222

期限:3年

日期:11/00/6789

结果文件应显示:

的差异:

档案1第4行:价格3:1234.00美元

文件-2第4行:价格3:$ 5678.00

文件-1第7行:期限:2年

文件-2第7行:期限:3年

非常感谢你。

嗨@ Ekkehard.Horner   非常感谢您的帮助和时间,并且能够容忍我的狡猾问题。   事实是,我试图理解你的代码越多,我就越困惑。   当我把这个代码放在Quick Test Pro_11中时,它会抛出语法错误@“Dim oDiffer:Set oDiffer = New cDiffer.init(”C:......“   QTP在“...新cDiffer”和“.init”之间说“预期结束”   QTP显示函数“TrailVersion”以及函数“GoldVersion”

中的错误

如果您对此有所了解,那将是非常好的。   是否有必要拥有“预期”文本文件......?因为我不想包含该部分,因为否则我将为我的每次比较创建“预期”文件。

请原谅我的狡猾问题。

提前致谢。

Class cDiffer   
Option Explicit  
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")  
    WScript.Quit TrialVersion() 
    WScript.Quit TinVersion()  
Function TinVersion()   
    WScript.Echo "can't compare files yet."   
    TinVersion = 1 
End Function ' TinVersion  
HERE I'VE COMMENTED TRIALVERSION FUNCTION 
Function TrialVersion()   
Dim oDiffer : Set oDiffer = New cDiffer.init("C:\Documents and Settings\24800\My Documents\PDF comparison\A_30120625003267.TXT", "C:\Documents and Settings\aa24800\My Documents\PDFcomparison\B_30120502002776.TXT", Array("Quote ID:", "Quote Summary for:", "Quote Date:", "Tracking ID (A):", "Tracking ID (Z):", "Tracking ID:")
    ' the differ should be able to return a result - the differences   
    Dim sRes : sRes = oDiffer.diffs()   
    ' check actual vs. expected result   
    Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()  
    WScript.Echo "--------- Res"   
    WScript.Echo sRes   
    If sExp = sRes Then      
        WScript.Echo "ok"      
        ' save result      
        goFS.CreateTextFile("C:\Documents and Settings\aa24800\My Documents\PDF comparison\Result.TXT", True).Write sRes      
        TrialVersion = 0   Else      
        ' show failure      
        WScript.Echo "--------- Exp"      
        WScript.Echo sExp      
        WScript.Echo "not ok"      
        TrialVersion = 1   
    End If 
End Function ' TrialVersion  
'trivial Differ 
'Class cDiffer   
    Dim m_sLFSpec : m_sLFSpec = "C:\Documents and Settings\aa24800\My Documents\PDF comparison\A_30120625003267.TXT"
Dim m_sRFSpec : m_sRFSpec = "C:\Documents and Settings\aa24800\My Documents\PDF comparison\B_30120502002776.TXT"   
    ' "constructor" with params   
    Public Function init(sLFSpec, sRFSpec)     
        Set init  = Me     
        m_sLFSpec = sLFSpec     
        m_sRFSpec = sRFSpec   
    End Function   
    Public Function diffs()     
        diffs = "cDiffer.diffs() not implemented yet."   
    End Function ' diffs 
'End Class ' cDiffer00
'gold Differ 
'Class cDiffer   
'   Private m_sLFSpec   ' file specs   
'   Private m_sRFSpec   
    Private m_sLFiNa    ' file names   
    Private m_sRFiNa   
    Private m_dicLabels ' store and efficiently find selective labels   
    ' "constructor" with params   
    Public Function init(sLFSpec, sRFSpec, aLabels)     
        Set init  = Me     
        m_sLFSpec = sLFSpec     
        m_sRFSpec = sRFSpec     
        m_sLFiNa  = goFS.GetBaseName(sLFSpec)     
        m_sRFiNa  = goFS.GetBaseName(sRFSpec)     
        Set m_dicLabels = CreateObject("Scripting.Dictionary")     
        m_dicLabels.CompareMode = vbTextCompare ' case-insensitive     
        Dim sKey     
        For Each sKey In aLabels         
            m_dicLabels(sKey) = 0     
        Next   
    End Function   
    Public Function diffs()     ' Use ArrayList to collect the results     
        Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")     
        ' requested title     
        alRes.Add "Differences:"     
        ' open both input files     
        Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)     
        Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)     
        ' loop over lines     
        Do Until tsL.AtEndOfStream        
            Dim sLL : sLL = tsL.ReadLine()        
            Dim sRL        
            ' second file could be shorter        
            If tsR.AtEndOfStream Then           
                alRes.Add "tsR.AtEndOfStream"           
        Exit Do        
            Else           
                sRL = tsR.ReadLine()        
            End If        
            ' no need for work if lines are equal        
            If sLL <> sRL Then           
                If m_dicLabels.Exists(Split(sLL, ":")(0))Then                  
                Dim sLiNo : sLiNo = CStr(tsL.Line - 1)& ":"              
            alRes.Add Join(Array(m_sLFiNa, "Line", sLiNo, sLL))              
            alRes.Add Join(Array(m_sRFiNa, "Line", sLiNo, sRL))           
            End If        
        End If     
    Loop     
    tsL.Close     
    tsR.Close     
    diffs = Join(alRes.ToArray(), vbCrLf) & vbCrLf   
End Function ' diffs 
End Class ' cDiffer

Function GoldVersion()   
   ' the differ should know about the files to compare   
   ' and the info labels to select   
   Dim oDiffer : Set oDiffer = New cDiffer.init("C:\Documents and Settings\aa24800\My Documents\PDF comparison\A_30120625003267.TXT", "C:\Documents and Settings\aa24800\My Documents\PDF comparison\B_30120502002776.TXT", Array("Quote ID:", "Quote Summary for:", "Quote Date:", "Tracking ID (A):", "Tracking ID (Z):", "Tracking ID:")
   ' the differ should be able to return a result - the differences    
   Dim sRes : sRes = oDiffer.diffs()   
   ' check actual vs. expected result   
   Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()   
   WScript.Echo "--------- Res"   
   WScript.Echo sRes   
    If sExp = sRes Then      
       WScript.Echo "ok"      
       ' save result      
       goFS.CreateTextFile("C:\Documents and Settings\aa24800\My Documents\PDF comparison\Result.TXT", True).Write sRes      
       GoldVersion = 0   Else      
       ' show failure      
       WScript.Echo "--------- Exp"      
       WScript.Echo sExp      
       WScript.Echo "not ok"      
       GoldVersion = 1   
    End If 
End Function ' GoldVersion

1 个答案:

答案 0 :(得分:1)

如果您是VBScript的新手,您可以从解决当前问题中获益 一种可以帮助您解决下一个问题的方法。

首先放置SelFileComp.vbs:

'' SelFileComp.vbs - selective file compare

Option Explicit

Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")

WScript.Quit TinVersion()

Function TinVersion()
  WScript.Echo "can't compare files yet."
  TinVersion = 1
End Function ' TinVersion

进入一些合适的目录。添加输入和预期结果文件。 启动SelFileComp.vbs:

cscript SelFileComp.vbs
can't compare files yet.
echo %ErrorLevel%
1

添加(并调用)准备和使用(普通)Differ对象的TrialVersion 在一个适合理智的骨架中进行繁重的检查实施:

'' SelFileComp.vbs - selective file compare

Option Explicit

Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")

WScript.Quit TrialVersion()
WScript.Quit TinVersion()

Function TinVersion()
  WScript.Echo "can't compare files yet."
  TinVersion = 1
End Function ' TinVersion

Function TrialVersion()
  ' the differ should know about the files to compare
  ' we'll worry about the selection later
  Dim oDiffer : Set oDiffer = New cDiffer.init( _
     "File-1", "File-2" _
  )
  ' the differ should be able to return a result - the differences
  Dim sRes : sRes = oDiffer.diffs()
  ' check actual vs. expected result
  Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()
  WScript.Echo "--------- Res"
  WScript.Echo sRes
  If sExp = sRes Then
     WScript.Echo "ok"
     ' save result
     goFS.CreateTextFile("..\data\Result", True).Write sRes
     TrialVersion = 0
  Else
     ' show failure
     WScript.Echo "--------- Exp"
     WScript.Echo sExp
     WScript.Echo "not ok"
     TrialVersion = 1
  End If
End Function ' TrialVersion

' trivial Differ
Class cDiffer
  Private m_sLFSpec
  Private m_sRFSpec
  ' "constructor" with params
  Public Function init(sLFSpec, sRFSpec)
    Set init  = Me
    m_sLFSpec = sLFSpec
    m_sRFSpec = sRFSpec
  End Function
  Public Function diffs()
    diffs = "cDiffer.diffs() not implemented yet."
  End Function ' diffs
End Class ' cDiffer00

输出:

cscript SelFileComp.vbs
--------- Res
cDiffer.diffs() not implemented yet.
--------- Exp
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year

not ok

echo %ErrorLevel%
1

如果您随后重命名了简单的cDiffer

' trivial Differ
Class cDiffer00

你可以重复使用这个名字(和TrialVersion()中的代码)来提出一个 cDiffer至少做了一些比较:

' simple Differ
Class cDiffer
  Private m_sLFSpec
  Private m_sRFSpec
  ' "constructor" with params
  Public Function init(sLFSpec, sRFSpec)
    Set init  = Me
    m_sLFSpec = sLFSpec
    m_sRFSpec = sRFSpec
  End Function
  Public Function diffs()
    ' Use ArrayList to collect the results
    Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")
    ' requested title
    alRes.Add "Differences:"
    ' open both input files
    Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
    Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)
    ' loop over lines
    Do Until tsL.AtEndOfStream
       Dim sLL : sLL = tsL.ReadLine()
       Dim sRL
       ' second file could be shorter
       If tsR.AtEndOfStream Then
          alRes.Add "tsR.AtEndOfStream"
          Exit Do
       Else
          sRL = tsR.ReadLine()
       End If
       ' no need for work if lines are equal
       If sLL <> sRL Then
          alRes.Add "??? " & sLL
          alRes.Add "??? " & sRL
       End If
    Loop
    tsL.Close
    tsR.Close
    diffs = Join(alRes.ToArray(), vbCrLf)
  End Function ' diffs
End Class ' cDiffer00

输出:

cscript SelFileComp.vbs
--------- Res
Differences:
??? Date: 00/11/1234 / Order no: 1111
??? Date: 11/00/6789 and Order no: 2222
??? Price 3: $1234.00
??? Price 3: $5678.00
??? Order no: 1111
??? Order no: 2222
??? Term: 2-Year
??? Term: 3-Year
??? Date: 00/11/1234
??? Date: 11/00/6789
--------- Exp
Differences:
File-1 Line 4: Price 3: $1234.00
File-2 Line 4: Price 3: $5678.00
File-1 Line 7: Term: 2-Year
File-2 Line 7: Term: 3-Year

not ok

这清楚地表明了哪些子任务仍有待完成:

  1. 选择相关差异
  2. 输出格式
  3. 让我们保持乐观并添加并调用GoldVersion()

    Function GoldVersion()
      ' the differ should know about the files to compare
      ' and the info labels to select
      Dim oDiffer : Set oDiffer = New cDiffer.init( _
          "File-1", "File-2" _
        , Array("Price 3", "Term") _
      )
      ' the differ should be able to return a result - the differences
      Dim sRes : sRes = oDiffer.diffs()
      ' check actual vs. expected result
      Dim sExp : sExp = goFS.OpenTextFile("Expected").ReadAll()
      WScript.Echo "--------- Res"
      WScript.Echo sRes
      If sExp = sRes Then
         WScript.Echo "ok"
         ' save result
         goFS.CreateTextFile("..\data\Result", True).Write sRes
         GoldVersion = 0
      Else
         ' show failure
         WScript.Echo "--------- Exp"
         WScript.Echo sExp
         WScript.Echo "not ok"
         GoldVersion = 1
      End If
    End Function ' GoldVersion
    

    有更好的cDiffer:

    ' gold Differ
    Class cDiffer
      Private m_sLFSpec   ' file specs
      Private m_sRFSpec
      Private m_sLFiNa    ' file names
      Private m_sRFiNa
      Private m_dicLabels ' store and efficiently find selective labels
      ' "constructor" with params
      Public Function init(sLFSpec, sRFSpec, aLabels)
        Set init  = Me
        m_sLFSpec = sLFSpec
        m_sRFSpec = sRFSpec
        m_sLFiNa  = goFS.GetBaseName(sLFSpec)
        m_sRFiNa  = goFS.GetBaseName(sRFSpec)
        Set m_dicLabels = CreateObject("Scripting.Dictionary")
        m_dicLabels.CompareMode = vbTextCompare ' case-insensitive
        Dim sKey
        For Each sKey In aLabels
            m_dicLabels(sKey) = 0
        Next
      End Function
      Public Function diffs()
        ' Use ArrayList to collect the results
        Dim alRes : Set alRes = CreateObject("System.Collections.ArrayList")
        ' requested title
        alRes.Add "Differences:"
        ' open both input files
        Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
        Dim tsR   : Set tsR   = goFS.OpenTextFile(m_sRFSpec)
        ' loop over lines
        Do Until tsL.AtEndOfStream
           Dim sLL : sLL = tsL.ReadLine()
           Dim sRL
           ' second file could be shorter
           If tsR.AtEndOfStream Then
              alRes.Add "tsR.AtEndOfStream"
              Exit Do
           Else
              sRL = tsR.ReadLine()
           End If
           ' no need for work if lines are equal
           If sLL <> sRL Then
              If m_dicLabels.Exists(Split(sLL, ":")(0)) Then
                 alRes.Add Join(Array(m_sLFiNa, "Line", sLL))
                 alRes.Add Join(Array(m_sRFiNa, "Line", sRL))
              End If
           End If
        Loop
        tsL.Close
        tsR.Close
        diffs = Join(alRes.ToArray(), vbCrLf)
      End Function ' diffs
    End Class ' cDiffer
    

    输出:

    cscript SelFileComp.vbs
    --------- Res
    Differences:
    File-1 Line Price 3: $1234.00
    File-2 Line Price 3: $5678.00
    File-1 Line Term: 2-Year
    File-2 Line Term: 3-Year
    --------- Exp
    Differences:
    File-1 Line 4: Price 3: $1234.00
    File-2 Line 4: Price 3: $5678.00
    File-1 Line 7: Term: 2-Year
    File-2 Line 7: Term: 3-Year
    
    not ok
    

    完成选择,格式化仍然不好。为了提高产量:

           If sLL <> sRL Then
              If m_dicLabels.Exists(Split(sLL, ":")(0)) Then
    '            alRes.Add Join(Array(m_sLFiNa, "Line", sLL))
    '            alRes.Add Join(Array(m_sRFiNa, "Line", sRL))
                 Dim sLiNo : sLiNo = CStr(tsL.Line - 1) & ":"
                 alRes.Add Join(Array(m_sLFiNa, "Line", sLiNo, sLL))
                 alRes.Add Join(Array(m_sRFiNa, "Line", sLiNo, sRL))
              End If
           End If
    

    添加尾随vbCrLf:

    '   diffs = Join(alRes.ToArray(), vbCrLf)
        diffs = Join(alRes.ToArray(), vbCrLf) & vbCrLf
    

    最终输出:

    cscript SelFileComp.vbs
    --------- Res
    Differences:
    File-1 Line 4: Price 3: $1234.00
    File-2 Line 4: Price 3: $5678.00
    File-1 Line 7: Term: 2-Year
    File-2 Line 7: Term: 3-Year
    
    ok
    
    echo %ErrorLevel%
    0
    

    下一个问题,拜托!

    更新A(文件规格/文件名称)

    将文件-1移动/复制到.. \ data \,更改

      Dim oDiffer : Set oDiffer = New cDiffer.init( _
          "File-1", "File-2" _
        , Array("Price 3", "Term") _
      )
    

      Dim oDiffer : Set oDiffer = New cDiffer.init( _
          "..\data\File-1", "File-2" _
        , Array("Price 3", "Term") _
      )
    

    结果将是相同的,因为cDiffer使用

    m_sLFSpec = sLFSpec
      to store the (full) path
    m_sLFiNa  = goFS.GetBaseName(sLFSpec)
      to extract the file name for output formatting
    Dim tsL   : Set tsL   = goFS.OpenTextFile(m_sLFSpec)
      to open the file
    

    更新B(wrt字典)

    dictionary是一个将元素存储在唯一键下的集合(如 与数组相对,这使得它的项目可以通过数字访问。通过 使用标签寻找字典的键,差异() 功能可以有效(看马,没有循环!)检查,是否 该行的第一部分:

      Split(sLL, ":")(0)
    

    包含在字典中

      If m_dicLabels.Exists(Split(sLL, ":")(0)) Then
    

    更新C(wrt类/构造函数)

    类是(一组相似的)对象的定义/规范,即a 变量保持/组合数据(成员)以及功能(方法)。 cDiffer是一个定义对象的类,它们“知道”所有要比较的文件和要查找的标签(成员变量,如m_sLSpec),并且可以“做”比较(方法/函数,如diffs())。 New语句用于根据规范构建/创建对象:

      Dim oDiffer : Set oDiffer = New cDiffer
    

    New创建的对象为Empty,对于实际用途来说是无用的;您可以 实现一个Class_Initialize()Sub(在Class ... End Class块中),但同样如此 代码将用于类的所有对象,增益很小。

    如果您查看Class语句的文档中的示例,那么您将会这样做 意识到,无参数'构造函数'(Class_Initialize)是 没有线/小时付费的程序员很少使用。锅炉板 代码

       Private Sub Class_Initialize
          m_CustomerName = ""
          m_OrderCount = 0
          ... ad nauseam: set all other member data to 'nix'
       End Sub
    

    特别恶心,因为VBScript

    • 自动执行等效的空Class_Initialize 你打电话给新
    • 将所有变量初始化为自动清空,清空将为 为字符串和数字工作正常

    补救措施是忘记Class_Initialize(特殊情况除外)和 在一个或多个方面投入一些努力

      Public Function initXXX(p1, p2, ... pn)
        Set initXXX = Me  ' return VBScript's this to caller
        ... use p1 ... pn to initialize member data to useful values
      End Function