List Info

Thread: repeated use of grep




repeated use of grep
country flaguser name
United States
2007-06-10 20:28:42

Hi, All -

Apologies for the length ...

A little context on what I am trying to do here. I use Slackware
Linux, which lacks the upgrading systems (like apt or yum) that other
Linux distributions have. So today I decided I would try to write a
Perl program to automate the upgrading of packages on a stable
Slackware box.

One of the things I am doing as part of this is building a data
structure that encapsulates the various package subdirectories, etc on
Slackware repositories/ftp sites, e.g would not only record the
package names but where the files "live" in Slackware repositories so
the program would know where to go to fetch a particular package if it
needed to be upgraded.

I figured the easiest way to do this would be to fetch the file
"PACKAGES.TXT" from the relevant Slackware mirror site and apply
various regexes to it to extract the information. This file contains
lines about each included package, including two contiguous lines for
each package that look like this:

PACKAGE NAME: a2ps-4.13b-i386-2.tgz
PACKAGE LOCATION: ./slackware/ap

... where "ap" is the name of the subdirectory on the repository.

At first I thought about trying to slurp in these pairs of lines as
units, but although I know the /s modifier makes * match newlines, I
couldn't figure that out. Then I decided to try slurping them into
separate arrays and then (somehow!) glomming them together with more
processing. But here is where I run into trouble. I can easily get
"lost in the regexes," so I started another small program to go step
by step. So far that program looks like this:

#!/usr/bin/perl

use warnings;
use strict;

open FH, "PACKAGES.TXT"
or die "Can't open file: $!";

my packages = grep /^PACKAGE NA/, <FH>;
my locations = grep /^PACKAGE LO/, <FH>;
print packages;
print locations;

close FH;

The current problem is that this prints out the PACKAGE NAME lines
fine, but doesn't print out any of the PACKAGE LOCATION lines. I must
be missing something really simple here (there ain't that many lines
of code), but I can't see it.

Any help with my failing eyesight is welcome. :^) I have a feeling
this is one of those things that is staring me in the face ...

Regards,

Glenn

__._,_.___
.

__,_._,___
Re: repeated use of grep
country flaguser name
United States
2007-06-10 23:55:27

>>&gt;>> "Glenn" == Glenn Becker < burningc%40sdf.lonestar.org">burningcsdf.lonestar.org&gt; writes:

Glenn>; my packages = grep /^PACKAGE NA/, <FH>;

This reads all the lines.

Glenn> my locations = grep /^PACKAGE LO/, <FH>;

Now there's no more lines to read here.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<; merlyn%40stonehenge.com">merlynstonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

__._,_.___
.

__,_._,___
Re: repeated use of grep
country flaguser name
United States
2007-06-11 01:25:55

Glenn,

The problem here is that the line

my packages = grep /^PACKAGE NA/, <FH>;

has already slurped through the entire file. You'd need to rewind
the file pointer back to the beginning by re-opening it before
looking through it again.

Better still might be to slurp the file in at one shot into an array,
and then go through that array looking for the text in question:

open FH, "PACKAGES.TXT&quot;
or die "Can't open file: $!";
my packagelines = <FH>; # slurp whole file into array
close FH;
chomp (packagelines); # kill all the newlines
my $line, packages, locations, $value;
foreach my $line (packagelines)
{
(undef, $value) = split(/: /, $line);
push (packages, $value) if ($line =~ m/^PACKAGE NA/);
push (locations, $value) if ($line =~ m/^PACKAGE LO/);
}
# Now we don't need the packagelines array, so nuke it:
packagelines = undef;

and from here you would then process the packages and locations
arrays to do whatever you wanted to with them.

Note that if there's only two pieces of information per package in
the PACKAGES.TXT file, you might want to use a hash instead of the
two arrays.

john

>
&gt;#!/usr/bin/perl
&gt;
>use warnings;
>use strict;
>
>open FH, "PACKAGES.TXT&quot;
>or die "Can't open file: $!";
>
&gt;my packages = grep /^PACKAGE NA/, <FH>;
>my locations = grep /^PACKAGE LO/, <FH>;
>print packages;
>print locations;
>
&gt;close FH;
>
>The current problem is that this prints out the PACKAGE NAME lines
&gt;fine, but doesn't print out any of the PACKAGE LOCATION lines. I must
>;be missing something really simple here (there ain't that many lines
&gt;of code), but I can't see it.
>
>Any help with my failing eyesight is welcome. :^) I have a feeling
>this is one of those things that is staring me in the face ...
>
>Regards,
>
>Glenn
>
--
John Francini, francini%40mac.com">francinimac.com

"The journey is more important than the destination -- that's part of life.
If you only live for getting to the end, you're almost always disappointed."
-- Donald Knuth

__._,_.___
.

__,_._,___
Re: repeated use of grep
country flaguser name
United States
2007-06-11 10:49:02

On Sunday 10 June 2007 18:28, Glenn Becker wrote:
&gt; Hi, All -

Hi.
[ . . ]
> A little context on what I am trying to do here. I use Slackware
> Linux, which lacks the upgrading systems (like apt or yum) that other
&gt; Linux distributions have. So today I decided I would try to write a
> Perl program to automate the upgrading of packages on a stable
&gt; Slackware box.

FWIW there's a (freely available) shell script (which I use) entitled
slackupdate that does just this.

But, with slackupdate, (there's one interim, manual step involved) which is
you run Slack's upgradepkg command on the updates after slackupdate downloads
the updates. (reasons do exist to the effect that this is a good thing).

I wrote my own Perl wrapper (enclosed below) for slackupdate which acts as the
control agent to control slackupdate. I shared this Perl wrapper with the
author of slackupdate. But I received no reply from the author of
slackupdate. And, yes, I know that this forks (launches a new or sub shell).

My intention is to one day rewrite slackupdate in Perl. But I must get
cracking for my shell script skills aren't advanced enough for me to fully
understand slackupdate. And my Perl skills may or may not be quite advanced
enough for me to do all of the things that slackupdate does.

If the OP desires, OP may email me private about I did a very slight mod to
slackupdate to make it work with my Perl wrapper. Though it's entirely
possible that it may be rather easy to see what's needed to do by studying my
Perl wrapper and by studying both slackupdate's options as well as all of the
functions that are in slackupdate (I set slackupdate to not check for a new
slackupdate version since I handle this in the Perl wrapper and do it only
every so often *when I want to do it*).

slackupdate itself can be downloaded from the darklinux url which is found at
almost the end of my Perl wrapper.

Here's my Perl wrapper:

#!/usr/bin/perl
use warnings;
use strict;

print "nChecking . . .nn";
my $txt;
my $junk;
my $blaklistd;
my stuff = `slackupdate -l 0 -s
ftp://slackware.mirrors.tds.net/pub/slackware`;
for ( stuff ) {
$blaklistd .= $_ if /Blacklisted/;
unless ( /Welcome|Initializing|Entering|Checking|Using|Blacklisted|^ / ) {
# print;
$txt .= $_;
}
}
shift stuff;
shift stuff;
$junk = pop stuff;
$junk = pop stuff;
$junk = pop stuff;
# $junk = pop stuff;
push stuff, $blaklistd if $blaklistd;
print stuff, "n&quot;;

my $choice;
if ($txt) {
$txt =~ s/nn//g;
print "Update(s) listed next were found at above servern&quot;;
print $txt;
print <<STUF;

The default is that we stop here without downloading.
If you've verified the changelog says no discontinued etc.
IOW "*only* updates to existing official packages are allowed here.";
Know also about slackupdate_blacklist when and why to use it.
If in doubt, just strike the enter key to end.
You *must* enter a 1 to download the new updates.
Or enter a 2 loads changelog in firefox and downloads updates
Or enter a 3 loads Updater version check in firefox and downloads updates
STUF
print "n**Read the above**&quot;;
print "nContinue? Enter a 1 or a 2 or 3 to download: ";
chomp($choice = <STDIN&gt;);
unless( $choice =~ /^1$|^2$|^3$/ ) {
$choice = 8;
}
}

$choice = 9 unless $txt;
if( $choice == 2 ) {
print "Downloading . . .n";
`firefox
http://slackware.mirrors.tds.net/pub/slackware/slackware-11.0/ChangeLog.txt`;
system( "slackupdate -s ftp://slackware.mirrors.tds.net/pub/slackware"; );
}elsif( $choice == 8 ) {
print "We ended without downloading because you didn't enter a 1 or 2 or
3n";;
}elsif( $choice == 1 ) {
print "Downloading . . .n";
system( "slackupdate -s ftp://slackware.mirrors.tds.net/pub/slackware"; );
}elsif( $choice == 3 ) {
print 'http://www.slackware.com/changelog/stable.php?cpu=i386', "n&quot;;
print "Downloading . . .n";
`firefox http://www.darklinux.net/slackupdate/`;
system( "slackupdate -s ftp://slackware.mirrors.tds.net/pub/slackware"; );
} else {
print "Your Slack is currently up2datenThere's no new updates at above
servern";
}
# end

--
Alan.

__._,_.___
.

__,_._,___
[1-4]

about | contact  Other archives ( Real Estate discussion Medical topics )