On May 07, 2004 at 19:37, Peter L. Buschman wrote:
>
> Thank you very much for the example below. It is quite helpful. In my
> case, reading the resource files directly is not an option so I have
> to parse the raw nsradmin output.
Hi,
Several years ago I did a perl module that correctly handles
the different possible cases of nsradmin output. I am also
including a little script that uses it so you can see how to
parse the output. This worked on both unix and windows at
the time.
HTH,
Byron
--- cut here sample.pl ---
#!/usr/bin/perl
use Nsradmin;
set_nsradmin("/usr/sbin/nsradmin");
$server = "myserver";
$query = "type: NSR";
$show = "";
$options = "";
@reslist = query($server, $query, $show, $options);
#
# A reslist is a list of resources. Resources are a
# hash of attributes, which have a name and value lists.
#
foreach $res (@reslist) {
%attrlist = %{$res};
foreach $attr (sort keys %attrlist) {
@vallist = @{$attrlist{$attr}};
printf "%s: ", $attr;
foreach $val (@vallist) {
printf "$val\t";
}
printf "\n";
}
}
--- cut here: Nsradmin.pm ----
package Nsradmin;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(
set_nsradmin
create_tmpfile
query
write_lines
$nsradmin
);
$nsradmin = "nsradmin";
1;
sub set_nsradmin {
my ($path) = @_;
$nsradmin = $path;
}
sub query {
my ($server, $query, $show, $options) = @_;
my @lines;
my @reslist;
my @reslines;
my %attrlist;
my $cmd;
my $append;
my $append_next;
# Prep the command to change display options
$options = "option $options";
# Prep the command for which attributes to show
$show = "show $show";
# Prep the command for the query to perform
$query = "print $query";
# Write the query to a temporary file
$queryfile = &write_lines($options, $show, $query);
# Determine the command to execute
$cmd = "$nsradmin -s $server -i $queryfile";
# Execute the query and parse the results
$append = 0;
open CMD, "$cmd |" || die "could not execute \"$cmd\"";
while (<CMD>) {
# Skip the option output
next if (/^Dynamic|Hidden|Resource/o);
# Skip the list of display options
if (/^Display options:/) {
# Read the next 3 lines
$_ = <CMD>;
$_ = <CMD>;
$_ = <CMD>;
next;
}
# Skip any show lines
next if (/^Will show all attributes/);
if ($append == 0 && /^\s*$/) {
#
# Blank lines start a new resource, but only if we are
not
# searching for the end of the previous attribute.
#
if (scalar @lines > 0) {
# The lines array represents a resource
push @reslines, [ @lines ];
@lines = ();
}
next;
}
# Eliminate leading and trailing whitespace only if we are not
# still searching for the end of an
s/^\s+// unless ($append);
s/\s+$// unless ($append);
if (/\\\s*$/) {
# Remove the backslash from the input line if it exists
s/\\\s*$//;
$append_next = 1;
}
# Determine if this line should be added to the previous line
or not
if ($append != 0) {
# Append this line to the last line in the array
$lines[$#lines] .= $_;
} elsif ($#lines != -1 && $lines[$#lines] !~ /;\s*/) {
#
# The previous line does not end with a semi-colon.
# Add the current line to the previous line
#
$lines[$#lines] .= $_;
} else {
# Add the ordinary line to the list of lines
push @lines, $_;
}
if ($lines[$#lines] !~ /;\s*/o) {
#
# The current line does not end with a semi-colon. The
# next line must be appended until one is found and the
# value list is complete.
#
$append_next = 1;
}
$append = $append_next;
$append_next = 0;
}
#
# Append the most recent set of lines to the results if there was no
# blank line at the end of the output
#
if (scalar @lines > 0) {
push @reslines, [ @lines ];
@lines = ();
}
# Delete the query file. The command pipeline closes itself.
unlink $queryfile;
#
# Separete the lines of each resource into a list of hashes. The hash
# keys are the attribute names and their values are a list of the
# attributes values.
#
foreach $lines (@reslines) {
%attrlist = ();
# The lines are in and compressed. Now separated them into a
hash
foreach $line (@$lines) {
if ($line =~ /(^[\w\s]+):(.*)$/ms) {
$attrname = $1;
$2 =~ /^\s*(.*);$/ms;
$value = $1;
# The following loop is from the book
# "Mastering Regular Expressions", page 205.
# Jeffrey Friedl, O'Reilly & Associates, Inc.
#
# It was modified to use the delimiter
# (, ) instead of a simle comma for use
# with RAP.
#
@vallist = ();
while ($value =~
m/"([^"\\]*(\\.[^"\\]*)*)"(,\s+)?|([^,]+)(,\s+)?|(,\s+)/g) {
push(@vallist, defined($1) ? $1 : $4);
}
push(@vallist, undef) if $value =~ m/,$/;
#
# Make sure the attribute is in the array,
# regardless of how many values it may or may
# not have.
#
$attrlist{$attrname} = ();
foreach $value (@vallist) {
#
# strip leading and trailing whitespace
from
# all values
#
$value =~ s/^\s+//;
$value =~ s/\s+$//;
# Skip empty values
next if (length $value == 0);
push @{$attrlist{$attrname}}, $value;
}
}
}
# Add the attrlist hash to the resource list
push @reslist, { %attrlist };
}
return @reslist;
}
sub create_tmpfile {
my $filename;
if (defined $ENV{TMPDIR}) {
$filename = $ENV{TMPDIR} . "/" . "tmp$$";
} elsif (defined $ENV{TMP}) {
$filename = $ENV{TMP} . "/" . "tmp$$";
} else {
$filename = "/tmp/" . "tmp$$";
}
}
sub write_lines {
my @lines = @_;
$tmpfile = &create_tmpfile;
open TMPFILE, "> $tmpfile" || die "could open $tmpfile for writting";
print TMPFILE join "\n", @lines;
print TMPFILE "\n";
close TMPFILE;
return $tmpfile;
}
1;
--
Note: To sign off this list, send a "signoff networker" command via email
to listserv AT listmail.temple DOT edu or visit the list's Web site at
http://listmail.temple.edu/archives/networker.html where you can
also view and post messages to the list.
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|