我有几个文本文件,每个文件有数千行,这是一个典型行的例子:
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
答案 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)
那样绕道而行。