Piercer has asked for the wisdom of the Perl Monks concerning the following question:
Hi all, I'm trying to do something fairly simple but can't figure out whats going wrong. I'm running NBTSTAT -a on a load of IP addresses - supplied from a file NBT.CSV -It's a windoze program which gives fairly verbose output - What I'm trying to get is the first 15 characters of each line with no duplicates in comma delimited form. A fairly simple text processing job I thought - I figured without me having left my brain at home today.
The code is as follows
#!c:\perl\bin\perl -w
open(NB, "nbt.csv")|| die"Cant open input file nbt.csv";
# NBT.CSV simply contains ip addresses - one per line
while(<NB>)
{undef $line;
chomp $_;
$line="$_".",";
@nbtstat = `nbtstat -a $_`;
$len=@nbtstat;
for ($j=0; $j<$len;$j++)
{$short=substr($nbtstat[$j],0,15);
chomp $short;
unless ($line=~m/$short/)
{$line=$line.",".$short;}
}
print "$line\n";
}
close(NB);
What I get is like this - first line is correct, second line is missing the ip address at the beginning - I cant figure out why?
1.1.1.1,,Host not found.
, Name ,---------------,Registered Regi,WS12345678901,USER1,MAC Address = 0
The text this is produced from is like this
C:\Perl>nbtstat -a 1.1.1.1
Host not found.
C:\Perl>nbtstat -a 1.1.1.2
NetBIOS Remote Machine Name Table
Name Type Status
---------------------------------------------
WS12345678901 <00> UNIQUE Registered
EUROPE-AFRICA <00> GROUP Registered
ws12345678901 <20> UNIQUE Registered
WS12345678901 <03> UNIQUE Registered
USER1 <03> UNIQUE Registered
MAC Address = 00-06-C7-E6-D8-36
Any ideas or donations of money would be gratefully received. Thanks Andrew
Re: Text processing question - strange output
by amelinda (Friar) on Nov 20, 2001 at 22:55 UTC
|
I'm not sure this is really "help," but rewriting like the following may help you track it down:
#!c:\perl\bin\perl -w
use strict; # you know you wanted this, right?
open(NB, "nbt.csv") or die "Can't open input nbt.csv\n";
# NBT.CSV simply contains ip addresses - one per line
while(<NB>)
{
chomp $_;
my $line="$_".","; # using my eliminates the undef
my @nbtstat = `nbtstat -a $_`; # my will make you happy
for ($j=0; $j<=$#nbstat;$j++) # $# is the last index
{
my $short=substr($nbtstat[$j],0,15);
chomp $short;
unless ($line=~m/$short/)
{$line=$line.",".$short;}
}
print "$line\n";
}
close(NB);
Update: Could we see an example of the output you are trying to achieve (generated by hand if necessary)? | [reply] [d/l] |
Re: Text processing question - strange output
by mkmcconn (Chaplain) on Nov 21, 2001 at 00:59 UTC
|
Piercer, I could not get your script to fail, but we seem to be using different versions of nbtstat.
I looked at your requirements, and although all the suggestions are good ones, it appears I might have something to offer in trying to satisfy all the requirements.
- get the first 15 characters of each line
- no duplicates
- in comma delimited form.
#!c:\perl\bin\perl -w
use strict;
# open(NB, "nbt.csv")|| die"Cant open input file nbt.csv";
# NBT.CSV simply contains ip addresses - one per line
# as DATA sample does
my %stathash = ();
while(my $ip = <DATA>){
chomp $ip;
#put nbtstat results in an array, one line = one element
my @nbtstat = split /\n/, `nbtstat -a $ip`;
#modify @nbtstat to discard gibberish (if desired)
for (@nbtstat){
s/^\s+//g;
$_ = substr($_,0,15);
s/[^a-z|A-Z|_|0-9|\040]//g;
s/\s+$//g;
}
# remove duplicates from array
my %uniq;
@nbtstat = grep { ! $uniq{$_} ++ } @nbtstat;
$stathash{$ip} = \@nbtstat;
}
for my $key (keys %stathash){
print "\n$key: \n";
#skip empty elements otherwise print to list
/.+/ and print "$_," for @{$stathash{$key}};
}
__DATA__
192.168.0.2
192.168.0.4
192.168.0.5
192.168.0.6
Result:
192.168.0.2:
Local Area Conn,Node IpAddress,Host not found,
192.168.0.4:
Local Area Conn,Node IpAddress,NetBIOS Remote,Name,OWL,TISIMAGING,MAC Address,
192.168.0.5:
Local Area Conn,Node IpAddress,NetBIOS Remote,Name,DELTA,TISIMAGING,MAC Address,
192.168.0.6:
Local Area Conn,Node IpAddress,NetBIOS Remote,Name,PANAMA,TISIMAGING,MAC Address,
mkmcconn
| [reply] [d/l] |
Re: Text processing question - strange output
by frankus (Priest) on Nov 20, 2001 at 22:56 UTC
|
Tried using strict? It's a good habit to aquire.
I think what you're trying to do can be done with this:
use strict;
open(NB, "nbt.csv") or die "Error reading nbt.csv: $!\n";
while(<NB>){
chomp;
@nbtstat = `nbtstat -a $_`;
%_=map{$_,1}map{/^\d+.\d+\.\d+\.\d+/;$&}($_,@nbtstat);
print join(',',$_,keys(%_)),"\n";
}
As I understand it, you want:
- nbtstat each IP address in the file (hopefully XXX.XXX.XXX.XXX, 15 chars ;)
-
Make a list of unique IP addresses (found at the beginning of each line returned)
- Print the list to STDOUT comma seperated
Or have I got the wrong end of the stick?
Note: this'll print the original IP address twice.
--
Brother Frankus.
¤ | [reply] [d/l] |
Re: Text processing question - strange output
by gryphon (Abbot) on Nov 20, 2001 at 23:52 UTC
|
Greetings Piercer,
I'm not entirely clear on what you want to gather and display, but from what I understand after reviewing your code, the following may be a solution:
#!/usr/bin/perl -w
use strict;
open(NB, 'nbt.csv') || die "Can't open input file: nbt.csv";
print join "\n", map { chomp; join ',', $_, map { chomp substr($_,0,15
+) } `nbtstat -a $_`; } <NB>;
close(NB);
Essentially, it prints out a bunch of lines, one line per IP address stored in the nbt.csv file. Each line has the first 15 characters of each line returned from the nbtstat command.
-gryphon
code('Perl') || die;
| [reply] [d/l] |
Re: Text processing question - strange output
by buckaduck (Chaplain) on Nov 20, 2001 at 23:28 UTC
|
The earlier suggestions for use strict; are good ones. It helps you catch typos in your code. I'm going to go out on a limb and guess that there's a typo near this line:
{$line=$line.",".$short;}
And that you may really have something else, like this:
{$line=$lin.",".$short;} # Oops, $lin should be $line
If you didn't do this originally, try to cut-and-paste code directly into the web browser when you submit a code sample. That way we can see if there are any typos in the original code. Your code, as you've written it here, seems to work for me.
buckaduck | [reply] [d/l] [select] |
|
|