Regexp Help

R

raven

The output of lpstat -p on hpux returns this:

printer sacprn05 is idle. enabled since Jul 30 12:23
fence priority : 0

I am attempting to grab the printer name and whether or not it is
idle. The code to do this is:

if (/^printer (\w+).*(enabled|disabled)/)

Is there a more efficient way to obtain the desired information using
a Perl regexp?
 
L

Lao Coon

(e-mail address removed) (raven) wrote in
The output of lpstat -p on hpux returns this:

printer sacprn05 is idle. enabled since Jul 30 12:23
fence priority : 0

I am attempting to grab the printer name and whether or not it is
idle. The code to do this is:

if (/^printer (\w+).*(enabled|disabled)/)

Is there a more efficient way to obtain the desired information using
a Perl regexp?

E.g. /^printer\s(\S+)/. Shorter is usually better, if you have little or
no variation in the input.

perl -MBenchmark -e "$a = 'printer sacprn05 is idle. enabled since Jul 30
12:23'; timethese(500000, {

'First' => '$a =~ /^printer (\w+).*(enabled|disabled)/;',

'Second' => '$a =~ /^printer\s(\S+)/;'

});"

Benchmark: timing 500000 iterations of First, Second...
First: 8 wallclock secs ( 7.19 usr + 0.02 sys = 7.21 CPU) @
69338.51/s (
n=500000)
Second: 1 wallclock secs ( 1.76 usr + 0.00 sys = 1.76 CPU) @
283607.49/s
(n=500000)
 
J

Jay Tilton

(e-mail address removed) (raven) wrote:

: The output of lpstat -p on hpux returns this:
:
: printer sacprn05 is idle. enabled since Jul 30 12:23
: fence priority : 0
:
: I am attempting to grab the printer name and whether or not it is
: idle. The code to do this is:
:
: if (/^printer (\w+).*(enabled|disabled)/)
:
: Is there a more efficient way to obtain the desired information using
: a Perl regexp?

What is your gauge of efficiency? I have to guess you want to
minimize runtime.

Why are you worrying about a match operation that takes microseconds
to perform? Unless it's going to happen a quadrillion times a day,
fuggetaboutit.

Anyway, the real time-killer will be invoking the external 'lpstat'
command.
 
R

raven

Thanks for the enlightening reply. Sorry for being vague in my
specification. I am simply tracking the printers, their IPs and the
current disabled/enabled status. In the future I'm sure I'll add more
functionality. Below is the the output of the various commands and the
hack.

lpstat -vsacprn05
device for sacprn05: /dev/null
remote to: RNP6C8BF9 on 192.168.25.73


#!/usr/contrib/bin/perl -w

# Printer interfaces directory
my $interface = "/etc/lp/interface";
# Printer Array
my @printers = ();

# Get a list of printers
open PRINTER, "lpstat -p |";
while (<PRINTER>) {
if (/^printer (\w+).*?(enabled|disabled)/) {
# Push an anonymous hash REFERENCE onto the array
push @printers, { "name" => "$1", "ip" => "none", "status" =>
"$2" };
}
}
close PRINTER;

# Gather the IP address of each printer
foreach $printer (@printers) {
open PRINTER, "lpstat -v$$printer{name} |";
while (<PRINTER>) {
next if /^device.*/;
if (/^\s+remote.*?(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/) {
$$printer{ip} = $1;
last;
}
}
close PRINTER;
# We hope that the printers with 'none' for IP are JetDirect
if ($$printer{ip} =~ /none/) {
open INTERFACE, "$interfaces/$$printer{name}" || die
"Cannot open file!\n";
while (<INTERFACE>) {
if (/^PERIPH=(.*)/) {
$$printer{ip} = $1;
last;
}
}
close INTERFACE;
}
}

# Display the results
foreach $printer (@printers) {
print "$$printer{name} / $$printer{ip} / $$printer{status}\n";
}
 
J

John W. Krahn

raven said:
Thanks for the enlightening reply. Sorry for being vague in my
specification. I am simply tracking the printers, their IPs and the
current disabled/enabled status. In the future I'm sure I'll add more
functionality. Below is the the output of the various commands and the
hack.

lpstat -vsacprn05
device for sacprn05: /dev/null
remote to: RNP6C8BF9 on 192.168.25.73

#!/usr/contrib/bin/perl -w

# Printer interfaces directory
my $interface = "/etc/lp/interface";
# Printer Array
my @printers = ();

# Get a list of printers
open PRINTER, "lpstat -p |";

You should _ALWAYS_ verify that the pipe opened correctly.

while (<PRINTER>) {
if (/^printer (\w+).*?(enabled|disabled)/) {
# Push an anonymous hash REFERENCE onto the array
push @printers, { "name" => "$1", "ip" => "none", "status" =>
"$2" };

Excessive quoting. The only thing that needs to be quoted is the string
'none'.

}
}
close PRINTER;

You should _ALWAYS_ verify that the pipe closed correctly.

# Gather the IP address of each printer
foreach $printer (@printers) {
open PRINTER, "lpstat -v$$printer{name} |";

You should _ALWAYS_ verify that the pipe opened correctly.

while (<PRINTER>) {
next if /^device.*/;
if (/^\s+remote.*?(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/) {
^ ^ ^
^ ^ ^
Dots are special in regular expressions. You need to escape them to
match a literal dot character.

$$printer{ip} = $1;
last;
}
}
close PRINTER;

You should _ALWAYS_ verify that the pipe closed correctly.

# We hope that the printers with 'none' for IP are JetDirect
if ($$printer{ip} =~ /none/) {
open INTERFACE, "$interfaces/$$printer{name}" || die
"Cannot open file!\n";

Using the || operator there won't do what you expect. You need to
either use the 'or' operator or parenthesize the open function.

while (<INTERFACE>) {
if (/^PERIPH=(.*)/) {
$$printer{ip} = $1;
last;
}
}
close INTERFACE;
}
}

# Display the results
foreach $printer (@printers) {
print "$$printer{name} / $$printer{ip} / $$printer{status}\n";
}


It looks like you just need one loop for all that:

#!/usr/contrib/bin/perl -w
use strict;

# Printer interfaces directory
my $interface = '/etc/lp/interface';
# Printer Array
my @printers;

# Get a list of printers
open PRINTER, 'lpstat -p |' or die "Cannot open pipe from lpstat: $!";
while ( <PRINTER> ) {

next unless /^printer (\w+).*?((?:dis|en)abled)/;
# Push an anonymous hash REFERENCE onto the array
push @printers, { name => $1, ip => 'none', status => $2 };

if ( `lpstat -v $printers[-1]{name}` =~
/^\s+remote.*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/m ) {
$printers[ -1 ]{ ip } = $1;
}
else {
local $/;
open INTERFACE, "$interfaces/$printers[-1]{name}"
or die "Cannot open $interfaces/$printers[-1]{name}: $!";
$printers[ -1 ]{ ip } = $1 if <INTERFACE> =~ /^PERIPH=(.*)/m;
close INTERFACE;
}
}
close PRINTER or die "Cannot close pipe from lpstat: $!";

# Display the results
foreach my $printer ( @printers ) {
print join( ' / ', @{$printer}{ qw/name ip status/ } ), "\n";
}



John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,137
Messages
2,570,795
Members
47,342
Latest member
eixataze

Latest Threads

Top