返回文本文件字符串搜索的行号或后续文本

时间:2013-05-28 01:56:10

标签: vbscript

我有几个文本文件,每个文件有数千行,这是一个典型行的例子:

PCI\VEN_10EC&DEV_8168&REV_09    Realtek\5x64\FORCED\PCIe_5.810.1218.2012\   Netrtle.inf Realtek 1   12/18/2012,5.810.1218.2012  Realtek PCIe GBE Family Controller

我正在处理的脚本对第一段文本进行字符串搜索:

PCI\VEN_10EC&DEV_8168&REV_09

我的脚本缩小了哪些文件有这个字符串,但我真正需要的是它然后在同一行返回下一个字符串:

Realtek\5x64\FORCED\PCIe_5.810.1218.2012\

一旦我有了这个字符串,我就可以继续使用从7zip中提取Realtek文件夹的脚本的其余部分。

我已经看到这已经在Stack上用其他语言完成了但是我找不到任何VBS的东西。如果我知道如何更好地表达任务,我可能会找到答案。我真的很感激有关抓住第二根弦的建议。

对于后台,这是我正在处理的脚本。它查看C:\ scripts \中的所有文本文件,查找由WMI查询为代码为28的设备驱动程序的CompatibleID返回的字符串(未安装驱动程序):

Set objFSO = CreateObject("Scripting.FileSystemObject") 
Set objShell = CreateObject("Wscript.Shell") 
Set objNet = CreateObject("WScript.Network") 
Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery _ 
    ("Select * from Win32_PnPEntity " _ 
        & "WHERE ConfigManagerErrorCode = 28") 
For Each objItem in colItems 
 Dim arrCompatibleIDs
 aarCompatibleIDs = objItem.CompatibleID
 for each objComp in aarCompatibleIDs
 Dim FirstID
 FirstID = objComp
Exit For
Next 
Next

strSearchFor = firstID
objStartFolder = "C:\scripts"

Set objFolder = objFSO.GetFolder(objStartFolder)

Set colFiles = objFolder.Files
For Each objFile in colFiles
    'Wscript.Echo objFile.Name
    strFile = "C:\scripts\" & objFile.Name
    set objFile = objFSO.getFile(strFile)
    if objFile.size > 0 then
        If InStr(objFSO.OpenTextFile(strFile).ReadAll, strSearchFor) > 0 Then
            msgbox(objfile.name)
        Else
            WScript.Sleep (100)
        End If
    End If
Next

2 个答案:

答案 0 :(得分:0)

如果需要在大海捞针中搜索固定针和可变线程,可以使用一些InStr()或RegExp。为了帮助您入门:

  Dim sHaystack : sHaystack = Join(Array( _
       "hay hay" _
     , "fixed_needle variable_thread hay" _
     , "hay hay" _
  ), vbCrLf)
  Dim sNeedle : sNeedle = "fixed_needle" & " "
  Dim nPosN   : nPosN   = Instr(sHaystack, sNeedle)
  If 0 < nPosN Then
     nPosN = nPosN + Len(sNeedle)
     Dim nPosT : nPosT = Instr(nPosN, sHaystack, " ")
     If 0 < nPosN Then
        WScript.Echo "Instr()", qq(Mid(sHaystack, nPosN, nPosT - nPosN))
     Else
        WScript.Echo "no thread"
     End If
  Else
     WScript.Echo "no needle"
  End If
  Dim reNT : Set reNT = New RegExp
  reNT.Pattern = sNeedle & "(\S+) "
  Dim oMTS : Set oMTS = reNT.Execute(sHayStack)
  If 1 = oMTS.Count Then
     WScript.Echo "RegExp ", qq(oMTS(0).SubMatches(0))
  Else
     WScript.Echo "no match"
  End If

输出:

Instr() "variable_thread"
RegExp  "variable_thread"

如果您将干草堆更改为

  Dim sHaystack : sHaystack = Join(Array( _
       "hay hay" _
     , "fixed_needle no_variable_thread_hay" _
     , "hay hay" _
  ), vbCrLf)

输出:

Instr() "no_variable_thread_hay
hay"
no match

你发现需要做更多工作才能使Instr()方法具有防弹性。

答案 1 :(得分:0)

由于您的输入文件似乎是以制表符分隔的,因此您可以执行以下操作:

Set wmi = GetObject("winmgmts://./root/cimv2")
qry = "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 28"
For Each entity In wmi.ExecQuery(qry)
  For Each cid In entity.CompatibleID
    firstID = cid
    Exit For
  Next
Next

Set fso = CreateObject("Scripting.FileSystemObject")
For Each f In objFSO.GetFolder(objStartFolder).Files
  If f.Size > 0 Then
    For line In Split(f.OpenAsTextStream.ReadAll, vbNewLine)
      arr = Split(line, vbTab)
      If arr(0) = firstID Then MsgBox arr(1)
    Next
  End If
Next

更一般地说,你不应该做这样的事情:

Set colFiles = objFolder.Files
For Each objFile in colFiles
  strFile = "C:\scripts\" & objFile.Name
  set objFile = objFSO.getFile(strFile)
  if objFile.size > 0 then
    If InStr(objFSO.OpenTextFile(strFile).ReadAll, strSearchFor) > 0 Then
...

Files集合已包含File个对象,因此从对象的属性(BTW包含Path属性)构建路径名完全没有意义这给你完整的路径)只获得你已经拥有的完全相同的对象。此外,文件对象有OpenAsTextStream方法,因此您可以直接将它们作为文本文件打开,而不必像objFSO.OpenTextFile(f.Path)那样绕道而行。