From: <db...@CT...> - 2003-04-08 18:04:00
|
Generally speaking, those characters shouldn't be a problem; just ignore them. I'm assuming you're just interested in the printable stuff. My approach is to match on one line at a time, and then parse that match (an arbitrary line) for the desired info, only because it's what I'm used to. In the Tcl version, this keeps the expect buffers flushing as you look for your match and this simulates more of a perlish feel. That's just personal preference. The point really is just parse out what you need and forget the rest. For the purpose of illustration, I'll assume you are looking for MAC addresses and ports they're on. So for each line where we see something that looks like a mac address followed by "Port: ", parse this stuff out and print it to stdout: #!/usr/local/bin/perl use Expect; $Expect::Log_Stdout=0; $session = Expect->spawn("/bin/cat /tmp/mac.txt"); $timeout = 10; expect($timeout, '-i', $session, '-re', "([^\r\n]+)[\r\n]+", sub { my $line = ($session->matchlist)[0]; if ($line =~ /(..-..-..-..-..-..).*Port:\s+(\d+)/) { print "mac $1 found on port $2\n"; } exp_continue; } ); I simply spawned a "cat" of the snippet of Catalyst output you included with your email to simulate the effect, but obviously this would be replaced with the login sequence and telnet specifics of a real session. I didn't bother doing the shift in the sub { } portion of code because I'm assuming that $session is the only object you have (i.e., you have spawned only one telnet to Catalyst switch). You can use fancier patterns if you feel it's warranted to eliminate ambiguity but that would be up to you. Hope this helps, David Basham CTC Communications John Mahoney <ex...@h0...t To: exp...@li... bi.com> cc: Sent by: Subject: [Expectperl-discuss] parsing non-ascii char's exp...@li...urc eforge.net 04/08/2003 08:38 AM Could use some tips on how to handle/translate non-ascii char's. I am using Expect.pm v 1.15 perl, v5.6.1 running on a Solaris 8 box. I am using expect to log into Nortel switches and I want to gather the forwarding database and vlan info. When I simply telnet into a switch, I can see the terminal screen cleared and then get text that looks like: MAC Address Table Aging Time: [ 300 seconds ] Find an Address: [ 00-00-00-00-00-00 ] Fast Aging: [ Enabled ] 00-00-86-1D-BF-BF Port: 11 00-00-86-4D-68-D4 Port: 1 etc, BUT it's really one long line with lots of special char's in it. I've tried several things including adding the line $exp->raw_pty(1); but, so far, I've been disappointed. I'm wondering if I can get Expect, IO:Stty, and/or IO:Tty to send me text that's easier to parse. -- Thx John Mahoney ex...@h0... ------------------------------------------------------- This SF.net email is sponsored by: ValueWeb: Dedicated Hosting for just $79/mo with 500 GB of bandwidth! No other company gives more support or power for your dedicated server http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ _______________________________________________ Expectperl-discuss mailing list Exp...@li... https://lists.sourceforge.net/lists/listinfo/expectperl-discuss |
From: BLACKSTONE, J. D. <jda...@ci...> - 2003-04-08 20:01:16
|
> -----Original Message----- > From: John Mahoney [mailto:ex...@h0...] > Sent: Tuesday, April 08, 2003 2:03 PM > To: db...@CT...; > exp...@li...; > exp...@li... > Subject: Re: [Expectperl-discuss] parsing non-ascii char's > > > Thx for your suggestion and I can see some merit here. > I am, however, starting to think I am off topic for this > list. > > My real problem is that I do not have multiple lines of > data to parse. It's all one long line with lots of > control chars. > > When I print the data to a file > cat <filename> > shows output that looks just like my telnet session. > cat -v <filename> > shows all the ugly special chars > wc -l <filename> > shows I have one line of data and > cat <filename> | wc -l > still tells me I have one line of data. > > I think I have to teach the script to break this output > into separate lines. > > Maybe this is an IO::Stty puzzle or something. I'm suspecting all you need is some training with regular expressions. Start with the Llama book, the Camel book, or the Perl regular expressions tutorial (http://www.perldoc.com/perl5.8.0/pod/perlretut.html) or quick start (http://www.perldoc.com/perl5.8.0/pod/perlrequick.html). You should be able to keep that one line and break it up into separate strings (try the split function) or use it over and over again with multiple operations. By and large, the presence of control characters and/or 8-bit characters shouldn't interfere with this, but if you need to represent a control character in a string or expression you can do so with for example "\cX" to represent control-X. jdb |
From: BLACKSTONE, J. D. <jda...@ci...> - 2003-04-08 20:10:23
|
> -----Original Message----- > From: Christian Goetze [mailto:cg...@hq...] > Sent: Tuesday, April 08, 2003 2:22 PM > To: exp...@li... > Subject: Re: [Expectperl-discuss] parsing non-ascii char's > > > > Thx for your suggestion and I can see some merit here. > > I am, however, starting to think I am off topic for this list. > > > > My real problem is that I do not have multiple lines of > > data to parse. It's all one long line with lots of > > control chars. > > > > When I print the data to a file > > cat <filename> > > shows output that looks just like my telnet session. > > cat -v <filename> > > shows all the ugly special chars > > wc -l <filename> > > shows I have one line of data and > > cat <filename> | wc -l > > still tells me I have one line of data. > > What you need here is a terminal emulator. If you're really > unlucky, the other side will optimize redraws and you will > not easily get the correct picture. As a first step, you > could simply try ignoring the special chars, but you may end > up having to emulate the screen and do "screen scraping". I have had to do some of that and it was not fun. Two things that might help you: If you capture your session to a file, write a program to "play it back" as a "movie" by clearing the screen and sending each character to the screen in sequence with a small delay in between (like 0.1 seconds). The terminal garbage may likely include codes that position the cursor. I think in my case those codes were something like escape, control-[ , row, semicolon, height, control-G. Or something awful like that; I can't remember what. But I could parse out the row and column and use it. I wrote a program to take a cut and paste terminal screen capture and print it out with - and | characters, with row and column numbers at the top and bottom. I made printouts of these to see where my data displayed, and checked the session capture log to make sure the row and column appeared exactly in the control garbage. Watching the movie also became important because sometimes things did not print out on the screen in the order you would expect. It would theoretically be possible to write a program that maintained an 80x24 "screen" array of characters, read the control codes, and updated the appropriate places in the array. If you do, put it on CPAN!!! But I didn't find it necessary. jdb |
From: John M. <ex...@h0...> - 2003-04-10 18:01:47
|
On Tue, Apr 08, 2003 at 03:10:44PM -0500, BLACKSTONE, J. DAVID wrote: > > > -----Original Message----- > > From: Christian Goetze [mailto:cg...@hq...] > > Sent: Tuesday, April 08, 2003 2:22 PM > > To: exp...@li... > > Subject: Re: [Expectperl-discuss] parsing non-ascii char's > > > > > > > Thx for your suggestion and I can see some merit here. > > > I am, however, starting to think I am off topic for this list. > > > > > > My real problem is that I do not have multiple lines of > > > data to parse. It's all one long line with lots of > > > control chars. > > > > > > When I print the data to a file > > > cat <filename> > > > shows output that looks just like my telnet session. > > > cat -v <filename> > > > shows all the ugly special chars > > > wc -l <filename> > > > shows I have one line of data and > > > cat <filename> | wc -l > > > still tells me I have one line of data. > > > > What you need here is a terminal emulator. If you're really > > unlucky, the other side will optimize redraws and you will > > not easily get the correct picture. As a first step, you > > could simply try ignoring the special chars, but you may end > > up having to emulate the screen and do "screen scraping". > > I have had to do some of that and it was not fun. Two things that might > help you: > > If you capture your session to a file, write a program to "play it back" > as a "movie" by clearing the screen and sending each character to the screen > in sequence with a small delay in between (like 0.1 seconds). > > The terminal garbage may likely include codes that position the cursor. I > think in my case those codes were something like escape, control-[ , row, > semicolon, height, control-G. Or something awful like that; I can't > remember what. But I could parse out the row and column and use it. I > wrote a program to take a cut and paste terminal screen capture and print it > out with - and | characters, with row and column numbers at the top and > bottom. I made printouts of these to see where my data displayed, and > checked the session capture log to make sure the row and column appeared > exactly in the control garbage. Watching the movie also became important > because sometimes things did not print out on the screen in the order you > would expect. > > It would theoretically be possible to write a program that maintained an > 80x24 "screen" array of characters, read the control codes, and updated the > appropriate places in the array. If you do, put it on CPAN!!! But I didn't > find it necessary. > > jdb Thanks to everyone for your help. The biggest things to help me were: use \c for reg exp's involving control chars; learning that someone else had faced text that included strings similar to "escape, control-[ , row, semicolon, height, control-G" etc (yuk!); reading my text with /usr/local/bin/less which is kind enough to display chars like "ESC[12;31HPort:"; Presently, I am successfully parsing this string with: #start by stripping the CTRL-[ chars $line =~ s/\c[//g; #strip the stupid NULL MAC $line =~ s/00-00-00-00-00-00//; #find the 1st MAC if ( $line =~ /(..\-..\-..\-..\-..\-..)/ ) { $first_mac = $1; } #throw away everything before the 1st MAC $line =~ s/^.*$first_mac/$first_mac/; #replace weird chars before each MAC $line =~ s/\[\d+\;1H/\n/g; #replace weird chars before each Port $line =~ s/\[\d+\;\d+H/\t/g; #find the last line and split it off if ( $line =~ m#\s+\[\d+K(Press\s.*)# ) { $last_line = $1; #(I need this $last_line data too) $line =~ s/\s+\[\d+KPress\s.*//; } @array = split ( /\n/, $line ); push ( @all_arrays, @array ); Seems like a lot a work to get what I want, but it works and I can get on with solving a problem. Thx again for all the help. -- John Mahoney ex...@h0... |
From: Roland G. <RGI...@cp...> - 2003-04-10 19:08:15
|
Sorry for replying so late... >> It would theoretically be possible to write a program that maintained an >>80x24 "screen" array of characters, read the control codes, and updated the >>appropriate places in the array. If you do, put it on CPAN!!! But I didn't >>find it necessary. It already is: Term::VT102 Complete with position-dependend triggers, a kind of 2-dimensional Expect. No need to reinvent the wheel... ;o) Hope this helps, Roland |
From: <db...@CT...> - 2003-04-08 22:50:59
|
hmm... That shouldn't matter. However to find all matches, the example I gave would have to be modified slightly. You can do multiple expect matches for a known pattern on a single input stream, or single line of text, etc.. . A modified example that would find all mac's on a single line of output would look something like this (below). Each time it matched on a MAC address, it would print it, and then jump back into the input stream looking for the next one: expect($timeout, '-i', $session, '-re', "(..-..-..-..-..-..)", sub { my $macAddr= ($session->matchlist)[0]; print "mac $macAddr found\n"; exp_continue; } ); of course, the only way out of this loop is timeout, so I'd probably throw in there something inthe way of a match to deal with your switch prompt. I Really think there should be no problem parsing this kind of input stream you describe. If you cannot get this working, only thing I can suggest is you might want to run using internal diagnostics turned on. (exp_internal=1 or something like this) and see what Expect is trying to match on. If it's just VT220 or something terminal emulation, then no reason expect cannot handle these characters, and line-by-line matching is not required for using an expect loop. John Mahoney <ex...@h0...ient2. To: db...@ct..., attbi.com> exp...@li..., exp...@li... 04/08/2003 03:03 PM cc: Subject: Re: [Expectperl-discuss] parsing non-ascii char's Thx for your suggestion and I can see some merit here. I am, however, starting to think I am off topic for this list. My real problem is that I do not have multiple lines of data to parse. It's all one long line with lots of control chars. When I print the data to a file cat <filename> shows output that looks just like my telnet session. cat -v <filename> shows all the ugly special chars wc -l <filename> shows I have one line of data and cat <filename> | wc -l still tells me I have one line of data. I think I have to teach the script to break this output into separate lines. Maybe this is an IO::Stty puzzle or something. Again, thx for your suggestion. -- Thx John Mahoney On Tue, Apr 08, 2003 at 01:53:32PM -0400, db...@CT... wrote: > > Generally speaking, those characters shouldn't be a problem; just ignore > them. I'm assuming you're just interested in the printable stuff. > > My approach is to match on one line at a time, and then parse that match > (an arbitrary line) for the desired info, only because it's what I'm used > to. In the Tcl version, this keeps the expect buffers flushing as you look > for your match and this simulates more of a perlish feel. That's just > personal preference. The point really is just parse out what you need and > forget the rest. > > For the purpose of illustration, I'll assume you are looking for MAC > addresses and ports they're on. So for each line where we see something > that looks like a mac address followed by "Port: ", parse this stuff out > and print it to stdout: > > #!/usr/local/bin/perl > > use Expect; > > $Expect::Log_Stdout=0; > > $session = Expect->spawn("/bin/cat /tmp/mac.txt"); > $timeout = 10; > > expect($timeout, > '-i', $session, > '-re', "([^\r\n]+)[\r\n]+", sub { > my $line = ($session->matchlist)[0]; > if ($line =~ /(..-..-..-..-..-..).*Port:\s+(\d+)/) { > print "mac $1 found on port $2\n"; > } > exp_continue; > } > ); > > I simply spawned a "cat" of the snippet of Catalyst output you included > with your email to simulate the effect, but obviously this would be > replaced with the login sequence and telnet specifics of a real session. I > didn't bother doing the shift in the sub { } portion of code because I'm > assuming that $session is the only object you have (i.e., you have spawned > only one telnet to Catalyst switch). You can use fancier patterns if you > feel it's warranted to eliminate ambiguity but that would be up to you. > > Hope this helps, > > David Basham > CTC Communications > > > > > > John Mahoney > <ex...@h0...t To: exp...@li... > bi.com> cc: > Sent by: Subject: [Expectperl-discuss] parsing non-ascii char's > exp...@li...urc > eforge.net > > > 04/08/2003 08:38 AM > > > > > > > Could use some tips on how to handle/translate non-ascii > char's. > > I am using Expect.pm v 1.15 > perl, v5.6.1 > running on a Solaris 8 box. > > I am using expect to log into Nortel switches and I want > to gather the forwarding database and vlan info. > > When I simply telnet into a switch, I can see the > terminal screen cleared and then get text that looks > like: > MAC Address Table > > Aging Time: [ 300 seconds ] > Find an Address: [ 00-00-00-00-00-00 ] > Fast Aging: [ Enabled ] > > 00-00-86-1D-BF-BF Port: 11 > 00-00-86-4D-68-D4 Port: 1 > etc, > BUT it's really one long line with lots of special > char's in it. > > I've tried several things including adding the line > $exp->raw_pty(1); > but, so far, I've been disappointed. I'm wondering if I > can get Expect, IO:Stty, and/or IO:Tty to send me text > that's easier to parse. > > -- > Thx > John Mahoney > ex...@h0... > > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > > > > |
From: John M. <ex...@h0...> - 2003-04-08 19:04:37
|
Thx for your suggestion and I can see some merit here. I am, however, starting to think I am off topic for this list. My real problem is that I do not have multiple lines of data to parse. It's all one long line with lots of control chars. When I print the data to a file cat <filename> shows output that looks just like my telnet session. cat -v <filename> shows all the ugly special chars wc -l <filename> shows I have one line of data and cat <filename> | wc -l still tells me I have one line of data. I think I have to teach the script to break this output into separate lines. Maybe this is an IO::Stty puzzle or something. Again, thx for your suggestion. -- Thx John Mahoney On Tue, Apr 08, 2003 at 01:53:32PM -0400, db...@CT... wrote: > > Generally speaking, those characters shouldn't be a problem; just ignore > them. I'm assuming you're just interested in the printable stuff. > > My approach is to match on one line at a time, and then parse that match > (an arbitrary line) for the desired info, only because it's what I'm used > to. In the Tcl version, this keeps the expect buffers flushing as you look > for your match and this simulates more of a perlish feel. That's just > personal preference. The point really is just parse out what you need and > forget the rest. > > For the purpose of illustration, I'll assume you are looking for MAC > addresses and ports they're on. So for each line where we see something > that looks like a mac address followed by "Port: ", parse this stuff out > and print it to stdout: > > #!/usr/local/bin/perl > > use Expect; > > $Expect::Log_Stdout=0; > > $session = Expect->spawn("/bin/cat /tmp/mac.txt"); > $timeout = 10; > > expect($timeout, > '-i', $session, > '-re', "([^\r\n]+)[\r\n]+", sub { > my $line = ($session->matchlist)[0]; > if ($line =~ /(..-..-..-..-..-..).*Port:\s+(\d+)/) { > print "mac $1 found on port $2\n"; > } > exp_continue; > } > ); > > I simply spawned a "cat" of the snippet of Catalyst output you included > with your email to simulate the effect, but obviously this would be > replaced with the login sequence and telnet specifics of a real session. I > didn't bother doing the shift in the sub { } portion of code because I'm > assuming that $session is the only object you have (i.e., you have spawned > only one telnet to Catalyst switch). You can use fancier patterns if you > feel it's warranted to eliminate ambiguity but that would be up to you. > > Hope this helps, > > David Basham > CTC Communications > > > > > > John Mahoney > <ex...@h0...t To: exp...@li... > bi.com> cc: > Sent by: Subject: [Expectperl-discuss] parsing non-ascii char's > exp...@li...urc > eforge.net > > > 04/08/2003 08:38 AM > > > > > > > Could use some tips on how to handle/translate non-ascii > char's. > > I am using Expect.pm v 1.15 > perl, v5.6.1 > running on a Solaris 8 box. > > I am using expect to log into Nortel switches and I want > to gather the forwarding database and vlan info. > > When I simply telnet into a switch, I can see the > terminal screen cleared and then get text that looks > like: > MAC Address Table > > Aging Time: [ 300 seconds ] > Find an Address: [ 00-00-00-00-00-00 ] > Fast Aging: [ Enabled ] > > 00-00-86-1D-BF-BF Port: 11 > 00-00-86-4D-68-D4 Port: 1 > etc, > BUT it's really one long line with lots of special > char's in it. > > I've tried several things including adding the line > $exp->raw_pty(1); > but, so far, I've been disappointed. I'm wondering if I > can get Expect, IO:Stty, and/or IO:Tty to send me text > that's easier to parse. > > -- > Thx > John Mahoney > ex...@h0... > > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Expectperl-discuss mailing list > Exp...@li... > https://lists.sourceforge.net/lists/listinfo/expectperl-discuss > > > > |
From: Christian G. <cg...@hq...> - 2003-04-08 19:24:01
|
> Thx for your suggestion and I can see some merit here. > I am, however, starting to think I am off topic for this > list. > > My real problem is that I do not have multiple lines of > data to parse. It's all one long line with lots of > control chars. > > When I print the data to a file > cat <filename> > shows output that looks just like my telnet session. > cat -v <filename> > shows all the ugly special chars > wc -l <filename> > shows I have one line of data and > cat <filename> | wc -l > still tells me I have one line of data. What you need here is a terminal emulator. If you're really unlucky, the other side will optimize redraws and you will not easily get the correct picture. As a first step, you could simply try ignoring the special chars, but you may end up having to emulate the screen and do "screen scraping". -- cg |