Page 1 of 1 1
Topic Options
#184260 - 2007-12-27 08:23 AM Scanning a file for non-blanks
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
Hi,

Stupid question i'm sure, but i'm a noob to KiX scripting (and this forum/community), but am a programmer by trade so answering this is hopefully not going to be too difficult for anyone here.

I'm looking for a good example of code (maybe from the UDF library) that can scan a text file one line at a time for non-blank strings so as to break those scanned lines down into smaller fields.

More specifically, for the input, a great example could be the output of a NETSTAT command piped into a text file, then scanned and broken down line by line into it's specific components (Proto,Local Address & Port,Foreign Address & Port, State, etc).

My feeling, as I said, is that this should be similar to something someone's already coded in the UDF and i could "borrow" the concept behind their code. Maybe it's something as simple conceptually as throwing each line into a single dimension 256 character array, then scanning character by character? Possibly there's an even more slick and finessed way to do it in KiX?

Anyone have any thoughts?

Thanks!

Top
#184261 - 2007-12-27 08:31 AM Re: Scanning a file for non-blanks [Re: jmuirh]
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4567
Loc: USA
Since you are familiar with the UDFs look for wshpipe().

Then, using your example it would be something like the following:

untested:
 Code:
for each $line in wshpipe('netstat',1)
  if len($line)>0
    ? $line
  endif
next


If you are needing to read text files, search for readfile().

Same idea as above:
untested:
 Code:
for each $line in readfile('file.txt')
  if len($line)>0
    ? $line
  endif
next

Top
#184262 - 2007-12-27 08:42 AM Re: Scanning a file for non-blanks [Re: Allen]
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4567
Loc: USA
I just reread your post, and I think I mis-understood your request. The udfs I suggested still apply but you will probably want to split() out the fields you need.

 Code:
for each $line in wshpipe('netstat',1)
  if instr($line,"WhatEverYouAreLookingFor")
    $Var=split($line," ")[3]  ; arrays are 0 based so this would be the 4th item
  endif
next

Top
#184266 - 2007-12-27 06:10 PM Re: Scanning a file for non-blanks [Re: Allen]
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
 Originally Posted By: Allen
I just reread your post, and I think I mis-understood your request. The udfs I suggested still apply but you will probably want to split() out the fields you need.

 Code:
for each $line in wshpipe('netstat',1)
  if instr($line,"WhatEverYouAreLookingFor")
    $Var=split($line," ")[3]  ; arrays are 0 based so this would be the 4th item
  endif
next


Cool! This is great. Thanks. It gets me a lot closer to what i'm trying to do.

One thing however... as far as the "WhateverYouAreLookingFor" portion of the code, i can't use it.

Essentially, i'm dealing with relatively unknown output. Both contents and positioning are variable.

All I know from the output is that it's structured in a way that the fields within the output are non-blank strings of characters, so basically I need to scan through each line until I find a non-blank character, continue scanning until I find blank again, lop that string of characters off into a field, and repeat until EOL.

John

Top
#184273 - 2007-12-27 08:21 PM Re: Scanning a file for non-blanks [Re: jmuirh]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11629
Loc: CA
There is also ASCAN if you place the elements into an array.
Top
#184280 - 2007-12-27 10:51 PM Re: Scanning a file for non-blanks [Re: NTDOC]
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
Again, that's helpful, but as far as the ability to scan for unknown content of an unknown length amongst blank characters, what's the best way?
Top
#184281 - 2007-12-27 11:20 PM Re: Scanning a file for non-blanks [Re: jmuirh]
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4567
Loc: USA
Depending on the output, you might have to be more specific as to what to split on. For example, some programs use a tab (chr 9).
 Code:
for each $line in wshpipe('netstat',1)
  for each $item in split($line," ") 
    ? $item
  next
next


Another way to do it would be to use RegEx. Search the board for examples.

Top
#184286 - 2007-12-28 12:44 AM Re: Scanning a file for non-blanks [Re: Allen]
Sealeopard Offline
KiX Master
*****

Registered: 2001-04-25
Posts: 11165
Loc: Boston, MA, USA
What exaxtly are you going to do with the file if the complete content of it is unknown? There may be better solutions if we woudl know the format/content of the input file.
_________________________
There are two types of vessels, submarines and targets.

Top
#184293 - 2007-12-28 02:04 AM Re: Scanning a file for non-blanks [Re: Sealeopard]
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
All i'm trying to do is capture the contents of a netstat into an array line by line, minus all the spacing. Look at the output of a "netstat" command at a c:\> prompt and tell me how you'd capture those individual variable pieces (protocol, address, port, etc.) into an array for manipulation or reformatting.
Top
#184294 - 2007-12-28 02:46 AM Re: Scanning a file for non-blanks [Re: jmuirh]
Sealeopard Offline
KiX Master
*****

Registered: 2001-04-25
Posts: 11165
Loc: Boston, MA, USA
you are contradicting yourself. On the one hand you want to read the output of NETSTAT specifically, but when someone provides you the necessary code, you then state you can't use it becasue the output you're trying to read is nonknown.

So, what is it? Are you trying to read the output from a NETSTAT command?

Then read the output line by line, discard the first to lines and use SPLIT to split the other lines into their four components. And that's essentially the code that was provided to you.
_________________________
There are two types of vessels, submarines and targets.

Top
#184297 - 2007-12-28 03:00 AM Re: Scanning a file for non-blanks [Re: Sealeopard]
Allen Administrator Offline
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4567
Loc: USA
This may not be exactly what you want, but I can tell you this works. You will have to make any changes if you want vars for the specific values, but this should be more than enough to go on.

 Code:
break on
$rc=setoption("wrapateol","on")

for each $line in wshpipe('netstat',1)
  if not instr($line,"Active Connection") and not instr($line,"Proto")
    for each $item in split($line," ") 
      if $item<>""
        $item + " "
      endif
    next
    ?
  endif
next

Top
#184299 - 2007-12-28 04:44 AM Re: Scanning a file for non-blanks [Re: Allen]
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
My apologies for the contradiction, as I wasn't aware that the split command can use/discard multiple spaces when specified as a delimiter. This should work. Thanks!
Top
#184301 - 2007-12-28 09:18 AM Re: Scanning a file for non-blanks [Re: jmuirh]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
 Originally Posted By: jmuirh
... I wasn't aware that the split command can use/discard multiple spaces when specified as a delimiter


It can't.

However, you can use the Join(Split()) replace trick to reduce multiple spaces to single characters before you parse the line.

There are some "squeeze()" or "compress()" UDFs knocking around, but it is easier to knock something up than search for it:


$sString=" A string with many spaces in it "
"Original string: '"+$sString+"'"+@CRLF
"Squeezed string: '"+udfSqueeze($sString)+"'"+@CRLF


Function udfSqueeze($s)
While InStr($s," ") $s=Join(Split($s," ")) Loop
$udfSqueeze=Trim($s)
Exit 0
EndFunction


Top
#184302 - 2007-12-28 10:05 AM Re: Scanning a file for non-blanks [Re: Richard H.]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Here is a fully working example:

Break ON
$=SetOption("Explicit","ON")


Dim $iStartLine,$iLineCount,$sLine


$iStartLine=5


For Each $sLine in Split(udfPipe("netstat")[0],@CRLF)
$sLine=udfSqueeze($sLine)
$iLineCount=$iLineCount+1
If $iLineCount>=$iStartLine AND $sLIne
$sLine=Split($sLine)
@CRLF+"INPUT LINE # "+$iLineCount+@CRLF
" Field 0 is Proto : "+$sLine[0]+@CRLF
" Field 1 is Local Address : "+$sLine[1]+@CRLF
" Host="+Split($sLine[1],":")[0]+", port="+Split($sLine[1],":")[1]+@CRLF
" Field 2 is Foreign Address : "+$sLine[2]+@CRLF
" Host="+Split($sLine[2],":")[0]+", port="+Split($sLine[2],":")[1]+@CRLF
" Field 4 is State : "+$sLine[3]+@CRLF
EndIf
Next


Function udfPipe($sCommand, Optional $iTimeout,Optional $iInterval) ; {{{
; Execute a command and return output and error streams
; This code adapted from Chris S. WshPipe() http://www.kixtart.org/ubbthreads/showflat.php?Cat=&Number=8257
Dim $oExec
Redim $udfPipe[2]


If Not $iTimeout $iTimeout=10.0 EndIf
If Not $iInterval $iInterval=0.1 EndIf
$iTimeout=CDbl($iTimeout)
$iInterval=CDbl($iInterval)


$oExec = CreateObject("WScript.Shell").Exec($sCommand)
If Not VarType($oExec)=9 $udfPipe[1]=@SERROR Exit @ERROR EndIf


; Wait for process to complete to ensure correct exit status is returned
While $oExec.Status=0 And $iTimeout > 0
Sleep $iInterval
$iTimeout=$iTimeout-$iInterval
Loop


If Not ($iTimeOut>0) $udfPipe[1]=$udfPipe[1]+@CRLF+"TIMER EXPIRED" Exit 1460 EndIf


$udfPipe[0] = $oExec.StdOut.ReadAll
$udfPipe[1] = $oExec.StdErr.ReadAll


Exit $oExec.ExitCode
EndFunction ;}}}
Function udfSqueeze($s) ;{{{
While InStr($s," ") $s=Join(Split($s," ")) Loop
$udfSqueeze=Trim($s)
Exit 0
EndFunction ;}}}
; vim: ai sw=4 ts=4 fdm=marker fdc=4



Output looks like this:
INPUT LINE # 5
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:1183
Host=xxxxxxxxxx10175, port=1183
Field 2 is Foreign Address : zzzzzlhdfl001.harsco.com:microsoft-ds
Host=zzzzzlhdfl001.harsco.com, port=microsoft-ds
Field 4 is State : ESTABLISHED


INPUT LINE # 6
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:1209
Host=xxxxxxxxxx10175, port=1209
Field 2 is Foreign Address : 999.999.0.43:1025
Host=999.999.0.43, port=1025
Field 4 is State : ESTABLISHED


INPUT LINE # 7
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:1213
Host=xxxxxxxxxx10175, port=1213
Field 2 is Foreign Address : mail.multiserv.com:5022
Host=mail.multiserv.com, port=5022
Field 4 is State : ESTABLISHED


INPUT LINE # 8
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:1677
Host=xxxxxxxxxx10175, port=1677
Field 2 is Foreign Address : yyyyyyyyws015.harsco.com:netbios-ssn
Host=yyyyyyyyws015.harsco.com, port=netbios-ssn
Field 4 is State : ESTABLISHED


INPUT LINE # 9
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:2107
Host=xxxxxxxxxx10175, port=2107
Field 2 is Foreign Address : 999.999.96.131:3502
Host=999.999.96.131, port=3502
Field 4 is State : TIME_WAIT


INPUT LINE # 10
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:2110
Host=xxxxxxxxxx10175, port=2110
Field 2 is Foreign Address : 999.999.96.131:3502
Host=999.999.96.131, port=3502
Field 4 is State : TIME_WAIT


INPUT LINE # 11
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:2111
Host=xxxxxxxxxx10175, port=2111
Field 2 is Foreign Address : 999.999.96.131:3502
Host=999.999.96.131, port=3502
Field 4 is State : TIME_WAIT


INPUT LINE # 12
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:1190
Host=xxxxxxxxxx10175, port=1190
Field 2 is Foreign Address : localhost:6139
Host=localhost, port=6139
Field 4 is State : ESTABLISHED


INPUT LINE # 13
Field 0 is Proto : TCP
Field 1 is Local Address : xxxxxxxxxx10175:6139
Host=xxxxxxxxxx10175, port=6139
Field 2 is Foreign Address : localhost:1190
Host=localhost, port=1190
Field 4 is State : ESTABLISHED


Top
#184303 - 2007-12-28 12:16 PM Re: Scanning a file for non-blanks [Re: Richard H.]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11629
Loc: CA
Thanks Richard. Looks great but does not seem to work here at home.
It's late here but I'll try to run it from work and see how it goes.

Just sits there for a very long time till I finally cancel it.

Using KIX32 v4.53

Top
#184304 - 2007-12-28 01:57 PM Re: Scanning a file for non-blanks [Re: NTDOC]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Hmm... the timeout stuff in the pipe UDF should ensure that it returns even if the netstat takes too long (the default is 10 seconds).

Try increasing the timeout (120 seconds for example) - if you are running the script from home the reverse lookups might be taking excessive time, though as I say the timeout *should* handle it.

Let me know what you find.

Top
#184317 - 2007-12-28 10:50 PM Re: Scanning a file for non-blanks [Re: Richard H.]
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11629
Loc: CA
Hmmmm... Tried again here at work. Let it run for 5 minutes and nothing. Script still open and cursor at a blinking line.
KIX32.EXE using just under 5MB in the process but does not increase or change. CPU activity not affected, so seems it's just stuck waiting for something.

A normal NETSTAT from DOS returns in a couple seconds.

Don't have time right now to debug but maybe weekend or later next week.

Hopefully someone else can try it out and see what their results are.

Top
#184321 - 2007-12-29 01:53 AM Re: Scanning a file for non-blanks [Re: NTDOC]
jmuirh Offline
Fresh Scripter

Registered: 2007-09-22
Posts: 21
This is all so cool. Thanks very much! As a noob to KiX scripting, this is a real great opportunity for education.

Thanks again!

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 1183 anonymous users online.
Newest Members
batdk82, StuTheCoder, M_Moore, BeeEm, min_seow
17885 Registered Users

Generated in 0.084 seconds in which 0.054 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org