• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2892
  • Last Modified:

help with loop in vbs script

Having some trouble grabbing disk info from this text file...my code works until a disk has been removed (denoted by (-)).
My code's a hack job, or I'd include it upfront.  If you need to see it, let me know...

Sample text file (irrelevant portions removed - I loop until I get to "Physical Devices Attached" then jump around till I get the info I need.  Again, it works on most reports, but hangs or doesn't report properly on this one)
   Physical Devices Attached
    SCSI Bus 0
     SCSI Target 0 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1P0S700007502E867
      Firmware Version ................. HPB7
     SCSI Target 1 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................(+) 3HW1P6SF00007502N2S5
                                     (-) 3HW1MTJC00007502D7BT
      Firmware Version ................. HPB7
     SCSI Target 2 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1NRJ100007502E6H4
      Firmware Version ................. HPB7
     SCSI Target 3 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1NXNF00007502PFBV
      Firmware Version ................. HPB7
    SCSI Bus 1
     SCSI Target 0 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1P5L500007502N3WF
      Firmware Version ................. HPB7
     SCSI Target 1 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1P7LN00007502D64X
      Firmware Version ................. HPB7
     SCSI Target 2 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1N25K00007502D6R1
      Firmware Version ................. HPB7
     SCSI Target 3 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1N92R00007502AAR2
      Firmware Version ................. HPB7
     SCSI Target 4 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1NQAE00007502B2ML
      Firmware Version ................. HPB7
     SCSI Target 5 ..................(-) COMPAQ  BF07285A36
      Capacity ......................(-) 69,461 MBytes (142255808 Blocks)
      Serial Number .................(-) 3HW1P58D00007502N4PJ
      Firmware Version ..............(-) HPB7
0
sirbounty
Asked:
sirbounty
  • 24
  • 17
1 Solution
 
mvidasCommented:
SB -
What are you trying to get from this file? How do you want the data returned to you?  I can create a function that you send the path/file to, but I just want to know what you want from it.
Matt
0
 
sirbountyAuthor Commented:
Haha - I guess that would be important for you to know, eh? :^)

Let me pull up my code and post the format I need it in...
0
 
sirbountyAuthor Commented:
From the first entry, I need bus, target, capacity.
SCSI Bus 0
     SCSI Target 0 ..................... COMPAQ  BF07285A36
      Capacity ......................... 69,461 MBytes (142255808 Blocks)
      Serial Number .................... 3HW1P0S700007502E867
      Firmware Version ................. HPB7

I want to return two variables.
x which would be the 'count' of the drives found
and
strDrives which would would contain 3 items for each disk found (bus, target,capacity, pipe-seperated, as 0|0|69,461|0|1|69,461 etc.)

I was using:
    strDrives = strDrives & strBus & "|" & strTarget & "|" & strCapacity & "|"
and just trimming off the last pipe after it was done - I don't know why this one doesn't work for me (only one out of about 90 files).  It only returns the first two entries.

let me know if you need anything further.
Thanx!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
mvidasCommented:
Add this to your vbs file:

Function SBDiskInfo(ByVal vPathFile)
 Dim ResultArr(), Cnt, FileCont(), fso, ts, RegEx, tStr, DriveArray(), iCnt, tempArr()
 
 'Redimension and initalize empty ResultArr array
 ReDim ResultArr(1) 'bound 0 will be count of drives found, bound 1 will be string of drives
 ResultArr(0) = 0
 ResultArr(1) = ""
 
 'initialize/set regex object, set initial pattern to only pull pertinent lines from file
 Set RegEx = New RegExp
 With RegEx
  .Global = False
  .IgnoreCase = True
  .MultiLine = False
  .Pattern = "SCSI (Bus|Target) \d+|Capacity \.+"
 End With
 
 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 Cnt = 0
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
 Set fso = Nothing
 Set ts = Nothing
 
 'if "Physical Devices Attached" not found in file, return blank array and
 If Cnt = 0 Then
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Loop through FileCont array, pulling data as needed
 iCnt = 0
 ReDim DriveArray(0)
 ReDim tempArr(2)
 For i = 0 To Cnt - 1
  RegEx.Pattern = "SCSI Bus (\d+)"
  If RegEx.Test(FileCont(i)) Then
   tempArr(0) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
  Else
   RegEx.Pattern = "SCSI Target (\d+)"
   If RegEx.Test(FileCont(i)) Then
    tempArr(1) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
   Else
    RegEx.Pattern = "Capacity \S+\s(.+?)\s"
    If RegEx.Test(FileCont(i)) Then
     tempArr(2) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
     ReDim Preserve DriveArray(iCnt)
     DriveArray(iCnt) = tempArr
     iCnt = iCnt + 1
    Else
     MsgBox "Uh oh!"
    End If
   End If
  End If
 Next
 
 'Check to make sure the previous For loop worked as desired
 If iCnt = 0 Then
  MsgBox "Something went severely wrong"
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Send results to ResultArr
 ResultArr(0) = iCnt
 For i = 0 To iCnt - 1
  If Len(ResultArr(1)) = 0 Then
   ResultArr(1) = Join(DriveArray(i), "|")
  Else
   ResultArr(1) = ResultArr(1) & "|" & Join(DriveArray(i), "|")
  End If
 Next
 
 SBDiskInfo = ResultArr
 'Dim ResultArr(), FileCont(), DriveArray(), tempArr()
 Set Cnt = Nothing
 Set RegEx = Nothing
 Set tStr = Nothing
 Set iCnt = Nothing
End Function

Example use:
 Dim tArr
 tArr = SBDiskInfo("C:\test.txt")
 MsgBox tArr(0) & " drives found." & vbCrLf & tArr(1)

I put a bunch of junk text in the sample file I had (from your original example) and it worked well, I'm curious to see if it works in your actual files.  If you get the "uh oh" or "something went severely wrong" msgbox's, let me know! Also if there is any other data in there you might want or want it in a different format, let me know as well.  I was going to return an array with the data in it, but instead I just pulled what you wanted from it (DriveArray).  This can be easily modified if you need it to get anything else from it too.

Matt
0
 
mvidasCommented:
I forgot to add that after running the above on your sample, I got:

10 drives found.
0|0|69,461|0|1|69,461|0|2|69,461|0|3|69,461|1|0|69,461|1|1|69,461|1|2|69,461|1|3|69,461|1|4|69,461|1|5|69,461
0
 
sirbountyAuthor Commented:
Thanx Matt - this is actually a very small piece of a large script.
90% of it is wmi queries.  This last 10% reads from a survey text file.
Since some results were missing, I generated a 'false' string of data that I'm replacing with valid data so that when I import it into a database, I'm not getting nulls or incorrect values...

I'm trying it out now...thanx!
0
 
sirbountyAuthor Commented:
11 drives found - and the last one (1/5) is invalid, as it contains the (-) (removed)
0
 
sirbountyAuthor Commented:
Another odd one.
It returns
11 drives found
then the 2nd line has
||135|0|0|etc,etc.<this is all correct up until drive 1/5>

Not sure where the 135 is coming from - nor the additional preceeding |

0
 
mvidasCommented:
Hi,
As for the (-) one, I wasn't sure if you wanted it included or not (I interpreted your mention of it originally to say that your code wasn't picking it up).

The 135 seems to be coming from a different part of the text file, in your junk text area.  There must be a line containing "Capacity .. 135" somewhere in that file (unknown number of "." characters).  Give the following a try, it will definately clear up the (-) ones (assuming the Capacity line contains the (-) for being removed).  This should hopefully remove the 135 too, but if not can you look in that specific text file for 135 and paste that part here? Change the .Pattern line to:
  .Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [a-z]+? \(\d+ [a-z]+?\)"
(line 15 or so in the function)

Not sure if you understand regular expressions, but now it looks for "Capacity " then an unknown number of "." characters that doesn't end in "(-)", then a space, then digits/commas (69,461), then another space, then letters (for MBytes, I left it as any letters in case you could also have KBytes or GBytes, etc), then another space, then "(", unknown amount of digits (142255808), another space, then letters (Blocks), then ")"
Hopefully your 135 line didn't fit that pattern completely.  If so I'll have to make it more specific, looking for ?Bytes and Blocks, etc.  If it will always have ?Bytes and Blocks in there, you can use:
  .Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [kmg]Bytes \(\d+ Blocks\)"

Might make it a little more specific for you.  Give it another shot, let me know how you make out.
Matt
0
 
mvidasCommented:
Also, if you wanted to change the text file so it started with Physical Devices Attached (to avoid the 135), change the regex and read file blocks to:

 'initialize/set regex object, set initial pattern to only pull pertinent lines from file
 Set RegEx = New RegExp
 With RegEx
  .Global = False
  .IgnoreCase = True
  .MultiLine = False
 End With
 
 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 tStr = ts.ReadAll
 ts.Close
 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  Set ts = fso.OpenTextFile(vPathFile, 2)
  ts.Write RegEx.Execute(tStr).Item(0)
  ts.Close
 End If
 Set ts = fso.OpenTextFile(vPathFile)
 Cnt = 0
 RegEx.Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [kmg]Bytes \(\d+ Blocks\)"
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
 Set fso = Nothing
 Set ts = Nothing

You wouldn't actually have to change the regex part of that, I just didn't see the need to set the pattern then change it without using the original.  Run time difference would not be noticeable if you set it originally.  Just a thought, in case my previous comment didn't work for your 135.
Matt
0
 
sirbountyAuthor Commented:
Sorry for the delay Matt - I hope to look at this today.
Thanx.
0
 
sirbountyAuthor Commented:
Ok - I just changed the regex as you first noted - it did remove the extra drive of course.
And I found the 135 - it's the total volume array size.  At some point in the future, I might decide to include that, I'm not sure - but for now, presumably I can just use this last code you posted?
0
 
sirbountyAuthor Commented:
Um - actually this won't work for me...it appears to be overwriting the original file... :(
0
 
mvidasCommented:
Hi SB,

Glad you were able to keep this open, sorry about the massive delay.  I changed it a little so it will create a temporary text file for the shortened file, without overwriting your original, and deletes if afterwards.  Here is the function again, though I only changed the "read file into array" block of code:


Function SBDiskInfo(ByVal vPathFile)
 Dim ResultArr(), Cnt, FileCont(), fso, ts, RegEx, tStr, DriveArray(), iCnt, tempArr()
 
 'Redimension and initalize empty ResultArr array
 ReDim ResultArr(1) 'bound 0 will be count of drives found, bound 1 will be string of drives
 ResultArr(0) = 0
 ResultArr(1) = ""
 
 'initialize/set regex object, set initial pattern to only pull pertinent lines from file
 Set RegEx = New RegExp
 With RegEx
  .Global = False
  .IgnoreCase = True
  .MultiLine = False
 End With
 
 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 tStr = ts.ReadAll
 ts.Close
 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  Set ts = fso.OpenTextFile(vPathFile, 2)
  ts.Write RegEx.Execute(tStr).Item(0)
  ts.Close
 End If
 Set ts = fso.OpenTextFile(vPathFile)
 Cnt = 0
 RegEx.Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [kmg]Bytes \(\d+ Blocks\)"
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
 If Right(vPathFile, 13) = ".deleteme.txt" Then
  fso.DeleteFile vPathFile
 End If
 Set fso = Nothing
 Set ts = Nothing
 
 'if "Physical Devices Attached" not found in file, return blank array and
 If Cnt = 0 Then
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Loop through FileCont array, pulling data as needed
 iCnt = 0
 ReDim DriveArray(0)
 ReDim tempArr(2)
 For i = 0 To Cnt - 1
  RegEx.Pattern = "SCSI Bus (\d+)"
  If RegEx.Test(FileCont(i)) Then
   tempArr(0) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
  Else
   RegEx.Pattern = "SCSI Target (\d+)"
   If RegEx.Test(FileCont(i)) Then
    tempArr(1) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
   Else
    RegEx.Pattern = "Capacity \S+\s(.+?)\s"
    If RegEx.Test(FileCont(i)) Then
     tempArr(2) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
     ReDim Preserve DriveArray(iCnt)
     DriveArray(iCnt) = tempArr
     iCnt = iCnt + 1
    Else
     MsgBox "Uh oh!"
    End If
   End If
  End If
 Next
 
 'Check to make sure the previous For loop worked as desired
 If iCnt = 0 Then
  MsgBox "Something went severely wrong"
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Send results to ResultArr
 ResultArr(0) = iCnt
 For i = 0 To iCnt - 1
  If Len(ResultArr(1)) = 0 Then
   ResultArr(1) = Join(DriveArray(i), "|")
  Else
   ResultArr(1) = ResultArr(1) & "|" & Join(DriveArray(i), "|")
  End If
 Next
 
 SBDiskInfo = ResultArr
 Set Cnt = Nothing
 Set RegEx = Nothing
 Set tStr = Nothing
 Set iCnt = Nothing
End Function


Please don't hesitate to ask if/when you need more help with this!
Matt
0
 
sirbountyAuthor Commented:
Thanx for following up - if it becomes an issue again, I'll implement this.
I had worked a similar solution and had to set it to not test the regexp until it hit a certain line for it to work on 'all' servers (nearly 200 of them).
So far, it's working fantastically (though I haven't verified every piece for every server just yet).
Thank you very much for your time and knowledge! :^)
0
 
mvidasCommented:
Well just let me know if you do need any more! The above fix would just get rid of that 135 total volume size (only start reading at "physical devices attached").  I'm guessing your star wars skills can help unlock this when the need arises, if it does lock again.  I have been curious if they're locked daily or if there is a "keep unlocked" flag - this question (and your deleted comment which probably says "keeping unlocked") answered that for me.
Let me know if/when you need any more help!
0
 
sirbountyAuthor Commented:
Haha - no, they're locked 7 days (after closure), and then every 7 days without further comment.
I can unlock them - but the deleted posts were actually pointers to other questions I'd asked, got no bites on, and then ended up resolving myself... :^)
0
 
mvidasCommented:
Interesting.. I only remember one deleted post (after http:#16489821 I think), that I actually went to check probably 15 minutes after you posted it and couldn't see it.  Made me miss oldlook!
0
 
sirbountyAuthor Commented:
Looks like I'll need that function after all - about 10 servers reported inaccurately...
0
 
sirbountyAuthor Commented:
If you're still around - here's the problem I've found with one server.
If you scan for Physical Devices Attached, the 'first' instance is a list of all 'removed' drives (ones preceeded with (-)).
So, naturally, it finds the total array size (101) as the 'first' valid drive, when in fact, it's not.
I'd hate to scan for the '2nd' instance of Physical Devices.  And I'm not sure (yet) if it's a static (search from the bottom to find the valid one).
Any ideas?
And I can certainly open a new question.  This has been a great function.  Only 10 failed to report accurately out of about 197 servers.  The rub is, they're running different versions of this tool, so I think that may be part of the problem... :(
0
 
sirbountyAuthor Commented:
Made a slight change:

If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  Set ts = fso.OpenTextFile(vPathFile, 2)

to

  Set ts = fso.CreateTextFile(vPathFile, 2)

I assume that's what you meant.
I wish I understood regexp a bit more - I might try to disect this myself.
I like the route you took with this though.  I had to use the same file to pull serial number info for a couple of devices.  I wonder if using regexp might not be a better method than the one I'm using...

Anyway - I'm still stuck though since the newly created file contains the (-) data 'first'... : (
I can post it if you'd like...
0
 
sirbountyAuthor Commented:
Ok - I stepped through it and this is what I found.
The .deleteme.txt file 'contained' all the right info, but for some reason, seemed to have skipped right over the Capacity lines (whetner (-) or not...)

Here's a sample of the data (.deleteme)
...starts with...
Physical Devices Attached
    SCSI Bus 0
     SCSI Target 0 ..................(-) COMPAQ  BF03685A35
      Capacity ......................(-) 34,732 MBytes (71132000 Blocks)
      Serial Number .................(-) 3HX14GZ300007402A8CA
      Firmware Version ..............(-) HPB4

1, 2, skip a few...then we have: (it 'was' picking up the 101 with the prior code - now I'm just getting a msgbox - "Something went horribly wrong")

    Array Logical Unit Information
     Fault Tolerance ................(+) Mirror (RAID 1)
     Capacity .......................(+) 101 GBytes (213392160 Blocks)
  Array Configuration
   Number of Logical Units ..........(+) 2
   SCSI Device Type on Bus 0 ........(+) unknown (00CF9005)
   SCSI Device Type on Bus 1 ........(+) unknown (00CF9005)
   Accelerator
    Memory ..........................(+) 112 KBytes (114,688)
    Battery Count ...................(+) 2                                                **** now on to the 'real' data...
   Physical Devices Attached
    SCSI Bus 0
     SCSI Target 0 ..................(+) COMPAQ  BF03685A35
      Capacity ......................(+) 34,732 MBytes (71132000 Blocks)
      Serial Number .................(+) 3HX14GZ300007402A8CA
      Firmware Version ..............(+) HPB4
0
 
sirbountyAuthor Commented:
By the way - I got around the limitation before by just using a boolean to determine if the loop had hit "Physcial Devices".  

If InStr(tStr, "Physical Devices") > 0 Then blnCheck = True

...and then just pulled the data if it was true...
0
 
mvidasCommented:
I am still around.. just got out of a horribly boring 2 hour meeting, need to take a quick break then I'll look through all this. No need to create another question, assuming I can help
0
 
sirbountyAuthor Commented:
Well if not a new thread - let's at least make this 500, cause you've helped me immensely...
0
 
mvidasCommented:
Points shmoints. I've got enough, and they're not going anywhere
As far as having multiple "Physical Devices Attached", change the part of the 'read file into array' block into

 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  tStr = RegEx.Execute(tStr).Item(0)
  Do Until Not RegEx.Test(Mid(tStr, 2))
   tStr = RegEx.Execute(Mid(tStr, 2)).Item(0)
  Loop
  Set ts = fso.OpenTextFile(vPathFile, 2, True)
  ts.Write tStr
  ts.Close
 End If

That will ensure that the .deleteme.txt file only has data starting with the LAST instance of "Physical devices attached".
Try that, see if it returns valid data for you.

RegExp is a huge helper for getting data from text files. Though practice is really the best teacher for it, I got my start with it from a knowledgebase entry that brettdj did for vbaexpress ( http://vbaexpress.com/kb/getarticle.php?kb_id=68 ).  It is in excel, but the idea is the same and the information is still good. I still keep his embedded word doc next to my computer for a handy reference, and I use it almost every time I do something in regexp (to make sure the syntax is correct).  I'm happy to help with any problems you have with it too, whether on or off EE.  I'd be happy to help you pull the serial number using it too, just need some sort of idea of what to do.  

Let me know how the above works for you though, and what is left to be done!
0
 
sirbountyAuthor Commented:
Hmm - getting an error - maybe I copied something down incorrectly or misunderstood you?

Here's what I have..

 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 tStr = ts.ReadAll
 ts.Close
 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  tStr = RegEx.Execute(tStr).Item(0)
  Do Until Not RegEx.Test(Mid(tStr, 2))
   tStr = RegEx.Execute(Mid(tStr, 2)).Item(0)
  Loop
  Set ts = fso.OpenTextFile(vPathFile, 2, True)
  ts.Write tStr
  ts.Close
 End If

 Cnt = 0
 RegEx.Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [kmg]Bytes \(\d+ Blocks\)"
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
0
 
mvidasCommented:
My email server (actually my webserver too) has been screwy the past couple days, sorry about the delay in getting back.
In your blank line there, we need to re-open the text file to read in:
 Set ts = fso.OpenTextFile(vPathFile)

The full block being:
 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 tStr = ts.ReadAll
 ts.Close
 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  tStr = RegEx.Execute(tStr).Item(0)
  Do Until Not RegEx.Test(Mid(tStr, 2))
   tStr = RegEx.Execute(Mid(tStr, 2)).Item(0)
  Loop
  Set ts = fso.OpenTextFile(vPathFile, 2, True)
  ts.Write tStr
  ts.Close
 End If
 Set ts = fso.OpenTextFile(vPathFile)
 Cnt = 0
 RegEx.Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?[^(][^-][^)] [\d,]+? [kmg]Bytes \(\d+ Blocks\)"
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
 If Right(vPathFile, 13) = ".deleteme.txt" Then
  fso.DeleteFile vPathFile
 End If
 Set fso = Nothing
 Set ts = Nothing

Matt
0
 
sirbountyAuthor Commented:
Thanx - trying now...
0
 
sirbountyAuthor Commented:
It seems to work on that one.
I'll push it out to all the servers and let you know the results.
Thanx!

Incidentally, I went through a couple of tutorials (not your post yet, but I will) and I was trying to come up with a pattern similar to yours that would simply 'exclude' the line from matching if it contained a (-).

I came up short though.  I opened a new q on it, if you'd like to swoop in and get some more :^)
http://www.experts-exchange.com/Programming/Q_21846563.html
0
 
sirbountyAuthor Commented:
I take that back - it created the proper .deleteme file with the data in it, but I still got the 'horribly wrong' msg.
I was stepping through it - I'll see if I can find where it missed...
0
 
mvidasCommented:
Hmm... give this whole function a try here, see how it works for you.  I'm posting in your other question there to explain the new regex match code, but the 'Loop through FileCont array" section changed a little bit to include the (+) ones:

Function SBDiskInfo(ByVal vPathFile)
 Dim ResultArr(), Cnt, FileCont(), fso, ts, RegEx, tStr, DriveArray(), iCnt, tempArr()
 
 'Redimension and initalize empty ResultArr array
 ReDim ResultArr(1) 'bound 0 will be count of drives found, bound 1 will be string of drives
 ResultArr(0) = 0
 ResultArr(1) = ""
 
 'initialize/set regex object, set initial pattern to only pull pertinent lines from file
 Set RegEx = New RegExp
 With RegEx
  .Global = False
  .IgnoreCase = True
  .MultiLine = False
 End With
 
 'read file into array, line by line, if it matches regex pattern
 Set fso = CreateObject("scripting.filesystemobject")
 Set ts = fso.OpenTextFile(vPathFile)
 tStr = ts.ReadAll
 ts.Close
 RegEx.Pattern = "Physical Devices Attached[^\x00]+"
 If RegEx.Test(tStr) Then
  vPathFile = vPathFile & ".deleteme.txt"
  tStr = RegEx.Execute(tStr).Item(0)
  Do Until Not RegEx.Test(Mid(tStr, 2))
   tStr = RegEx.Execute(Mid(tStr, 2)).Item(0)
  Loop
  Set ts = fso.OpenTextFile(vPathFile, 2, True)
  ts.Write tStr
  ts.Close
 End If
 Set ts = fso.OpenTextFile(vPathFile)
 Cnt = 0
' RegEx.Pattern = "SCSI (Bus|Target) \d+|Capacity \.+?\(?[^-]\)? [\d,]+? [kmg]Bytes \(\d+ Blocks\)"
 RegEx.Pattern = "SCSI Bus \d+|SCSI Target \d+\s*\.*\(?[^-]\)?|Capacity \.+\(?[^-]\)? [\d,]+ [kmg]Bytes \(\d+ Blocks\)"
 Do Until ts.AtEndOfStream
  tStr = ts.ReadLine
  If RegEx.Test(tStr) Then
   ReDim Preserve FileCont(Cnt)
   FileCont(Cnt) = tStr
   Cnt = Cnt + 1
  End If
 Loop
 ts.Close
 If Right(vPathFile, 13) = ".deleteme.txt" Then
  fso.DeleteFile vPathFile
 End If
 Set fso = Nothing
 Set ts = Nothing
 
 'if "Physical Devices Attached" not found in file, return blank array and
 If Cnt = 0 Then
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Loop through FileCont array, pulling data as needed
 iCnt = 0
 ReDim DriveArray(0)
 ReDim tempArr(2)
 For i = 0 To Cnt - 1
  RegEx.Pattern = "SCSI Bus (\d+)"
  If RegEx.Test(FileCont(i)) Then
   tempArr(0) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
  Else
   RegEx.Pattern = "SCSI Target (\d+)\s*\.*\(?[^-]\)?"
   If RegEx.Test(FileCont(i)) Then
    tempArr(1) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
   Else
    RegEx.Pattern = "Capacity \S+\(?[^-]\)?\s(.+?)\s"
    If RegEx.Test(FileCont(i)) Then
     tempArr(2) = RegEx.Execute(FileCont(i)).Item(0).SubMatches(0)
     ReDim Preserve DriveArray(iCnt)
     DriveArray(iCnt) = tempArr
     iCnt = iCnt + 1
    Else
     MsgBox "Uh oh!"
    End If
   End If
  End If
 Next
 
 'Check to make sure the previous For loop worked as desired
 If iCnt = 0 Then
  MsgBox "Something went severely wrong"
  SBDiskInfo = ResultArr
  Exit Function
 End If
 
 'Send results to ResultArr
 ResultArr(0) = iCnt
 For i = 0 To iCnt - 1
  If Len(ResultArr(1)) = 0 Then
   ResultArr(1) = Join(DriveArray(i), "|")
  Else
   ResultArr(1) = ResultArr(1) & "|" & Join(DriveArray(i), "|")
  End If
 Next
 
 SBDiskInfo = ResultArr
 Set Cnt = Nothing
 Set RegEx = Nothing
 Set tStr = Nothing
 Set iCnt = Nothing
End Function


It worked for me using your sample data from the other question, hopefully this full function will remove the error on your part.
Matt
0
 
sirbountyAuthor Commented:
Now that's hitting it...brb
0
 
sirbountyAuthor Commented:
Beautiful! :^)

I'm going to deploy it now and see what surfaces.
I think I may add a few things in the near future.
I may want to add each drive's serial number - though that might be difficult(?) since there's more than 'drive' serial numbers in these files.
And I think I'd like to see what can be done with my current function using regexes against finding the tape backup unit's serial numbers.
I will post seperate questions for these and place their pointer here.

Thanx so very much Matt!  
0
 
mvidasCommented:
The 'severely wrong' message doesn't appear because the container variable is overwritten, its because the individual regex.patterns of the FiltCont loop aren't matching anything in the array.  I'm guessing it is because of the different regex patterns and the (+), but if not we'll have to take a closer look
0
 
mvidasCommented:
Getting the serial numbers shouldn't be a problem, but it would probably take a slight change in logic (since we effectively 'close' the information we need from each drive once we reach capacity now).
Though thinking about it, it really wouldn't change much.  I guess it depends on how/where the other serial numbers are located within the files
Either way we can get it, I'm fairly confident of that.
The serial number thing should be easy as well, as long as theres some kind of pattern to follow to retrieve it
0
 
sirbountyAuthor Commented:
Okay - if/when I decide to go that route, I think I would rather email you a few sample files (I'd rather not post them as they 'do' contain some company-specific information)...I'll let you know.

I'd realized my mistake in the above post about overwriting the variable (I edited it, in case you're wondering where it went) - thought I'd caught it before you did - guess not..haha.
0
 
mvidasCommented:
And by the way, I love regex questions because it gives me more practice.  Though I'd say I'm pretty familiar with them, I wouldn't necessarily say I'm a regex expert (even just in VBS regexp, which is the least robust one).  
Some other regexp versions, like perl's I'm told, have a few other features that would make things so much easier (there is something that would allow us to avoid the (-) much easier, without the workarounds we have to use here, with a negative string match like "anything but (-)")
0
 
mvidasCommented:
I did notice the comment was gone, but I figured I'd address it anyways :)
Emailing me the files is a fine idea, I can also give you a link to my site to upload the files there.  Right now my email seems to be working ok, but the past 24 hours have been sporatic at best.  If it does go down I can even give you my work address, which would be fine for daytime help
0
 
sirbountyAuthor Commented:
I've got a few places to post them as well (ee-stuff for one), so if/when I decide to go that route, I'll see that you get the files and will post a "I'm ready" comment at that time...
Thanx again very much for your help!
0
 
mvidasCommented:
Thats why I'm here! Helping someone like you is just a bonus
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 24
  • 17
Tackle projects and never again get stuck behind a technical roadblock.
Join Now