[19080] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 1275 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Jul 11 03:26:50 2001

Date: Wed, 11 Jul 2001 00:26:35 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <994836395-v10-i1275@ruby.oce.orst.edu>
Content-Type: text

Perl-Users Digest           Wed, 11 Jul 2001     Volume: 10 Number: 1275

Today's topics:
        FAQ: What modules and extensions are available for Perl <faq@denver.pm.org>
        file date <e.quesada@verizon.net>
    Re: file date rik@tidi.be
    Re: file date (TuNNe|ing)
    Re: File properties with Perl (win32) (I'm a newbie) nobull@mail.com
    Re: Filtering mail based on size <no_sp@m.for_me.org>
        forking ChangeNotify's <neil@alaweb.com>
    Re: forking ChangeNotify's <goldbb2@earthlink.net>
        ftp script <todd@designsouth.net>
        fuzzy string comparision? <kmojar@bmjgroup.com>
    Re: fuzzy string comparision? <ubl@schaffhausen.de>
    Re: fuzzy string comparision? (Eric Bohlman)
        Getting Byref Argument <anilk@broden.com>
        Graphviz (was "family tree" generator) <kenneth@akerne-orchids.com>
        greping records from file through file - code fix (S H A N)
    Re: greping records from file through file - code fix (Logan Shaw)
    Re: greping records from file through file - code fix (S H A N)
    Re: Grouping and sorting <goldbb2@earthlink.net>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Wed, 11 Jul 2001 06:17:02 GMT
From: PerlFAQ Server <faq@denver.pm.org>
Subject: FAQ: What modules and extensions are available for Perl?  What is CPAN?  What does CPAN/src/... mean?
Message-Id: <ybS27.21$T3.176125952@news.frii.net>

This message is one of several periodic postings to comp.lang.perl.misc
intended to make it easier for perl programmers to find answers to
common questions. The core of this message represents an excerpt
from the documentation provided with every Standard Distribution of
Perl.

+
  What modules and extensions are available for Perl?  What is CPAN?  What does CPAN/src/... mean?

    CPAN stands for Comprehensive Perl Archive Network, a ~700mb archive
    replicated on nearly 200 machines all over the world. CPAN contains
    source code, non-native ports, documentation, scripts, and many
    third-party modules and extensions, designed for everything from
    commercial database interfaces to keyboard/screen control to web walking
    and CGI scripts. The master web site for CPAN is http://www.cpan.org/
    and there is the CPAN Multiplexer at http://www.perl.com/CPAN/CPAN.html
    which will choose a mirror near you via DNS. See
    http://www.perl.com/CPAN (without a slash at the end) for how this
    process works. Also, http://mirror.cpan.org/ has a nice interface to the
    http://www.cpan.org/MIRRORED.BY mirror directory.

    See the CPAN FAQ at http://www.cpan.org/misc/cpan-faq.html for answers
    to the most frequently asked questions about CPAN including how to
    become a mirror.

    CPAN/path/... is a naming convention for files available on CPAN sites.
    CPAN indicates the base directory of a CPAN mirror, and the rest of the
    path is the path from that directory to the file. For instance, if
    you're using ftp://ftp.funet.fi/pub/languages/perl/CPAN as your CPAN
    site, the file CPAN/misc/japh is downloadable as
    ftp://ftp.funet.fi/pub/languages/perl/CPAN/misc/japh .

    Considering that there are close to two thousand existing modules in the
    archive, one probably exists to do nearly anything you can think of.
    Current categories under CPAN/modules/by-category/ include Perl core
    modules; development support; operating system interfaces; networking,
    devices, and interprocess communication; data type utilities; database
    interfaces; user interfaces; interfaces to other languages; filenames,
    file systems, and file locking; internationalization and locale; world
    wide web support; server and daemon utilities; archiving and
    compression; image manipulation; mail and news; control flow utilities;
    filehandle and I/O; Microsoft Windows modules; and miscellaneous
    modules.

    See http://www.cpan.org/modules/00modlist.long.html or
    http://search.cpan.org/ for a more complete list of modules by category.

- 

Documents such as this have been called "Answers to Frequently
Asked Questions" or FAQ for short.  They represent an important
part of the Usenet tradition.  They serve to reduce the volume of
redundant traffic on a news group by providing quality answers to
questions that keep coming up.

If you are some how irritated by seeing these postings you are free
to ignore them or add the sender to your killfile.  If you find
errors or other problems with these postings please send corrections
or comments to the posting email address or to the maintainers as
directed in the perlfaq manual page.

Answers to questions about LOTS of stuff, mostly not related to
Perl, can be found by pointing your news client to

    news:news.answers

or to the many thousands of other useful Usenet news groups.

Note that the FAQ text posted by this server may have been modified
from that distributed in the stable Perl release.  It may have been
edited to reflect the additions, changes and corrections provided
by respondents, reviewers, and critics to previous postings of
these FAQ. Complete text of these FAQ are available on request.

The perlfaq manual page contains the following copyright notice.

  AUTHOR AND COPYRIGHT

    Copyright (c) 1997-1999 Tom Christiansen and Nathan
    Torkington.  All rights reserved.

This posting is provided in the hope that it will be useful but
does not represent a commitment or contract of any kind on the part
of the contributers, authors or their agents.

                                                           02.06
-- 
    This space intentionally left blank


------------------------------

Date: Tue, 10 Jul 2001 13:59:20 GMT
From: "Scaramouche" <e.quesada@verizon.net>
Subject: file date
Message-Id: <YSD27.395$Nt5.52455@dfiatx1-snr1.gtei.net>

i currently have a perl script that uses opendir and readdir for a listing
of files within a certain directory.  however, this just returns the file
name(s) that are currently present when i run the script.  is there a way of
getting the file date also?  this script returns back the number of users
logged into a certain db so i need to know just when they logged in.
i'm trying to stay away from using system() calls such as dir.
the script runs on a winnt box and the dir it reads is (i believe) ntfs.

&date;
system("cls");
print ("\t[ $date:$time ]\n\n");
$directory = "z:/some/dir";
opendir(Dir, $directory) || die ("Could not open $directory.");
@allFilesWithinDir=readdir(Dir);

foreach $fileNames (@allFilesWithinDir)
{
        # only interested in files within specified dir
        if(-d "$directory/$fileNames"){next}
        # use escape sequence to print $fileNames in lowercase
        print ("\L$fileNames\n");
}
closedir(Dir);

# date function
sub date
{
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
 @months = ("1","2","3","4","5","6","7","8","9","10","11","12");
 @days = ("Sun","Mon","Tue","Wed","Thur","Fri","Sat");
        if ($sec < 10) {$sec = "0$sec";}
        if ($min < 10) {$min = "0$min";}
        if ($hour < 10) {$hour = "0$hour";}
        if ($hour > 11) {$ampm = "PM";}
        if ($hour < 12) {$ampm = "AM";}
        if ($mday < 10) {$mday = "0$mday";}
 $millyear = $year + 1900;
 $date = "@days[$wday] @months[$mon]/$mday/$millyear";
 $time = "$hour:$min:$sec:$ampm";

tia,
rick




------------------------------

Date: Tue, 10 Jul 2001 16:06:36 +0200
From: rik@tidi.be
Subject: Re: file date
Message-Id: <3B4B0BEC.DC2C385B@tidi.be>

@a=stat (filename)
print $a[9];

Btw: this gives you the modification date in Unix format .... (=seconds since
1970 ?)

regards

rik

Scaramouche wrote:

> i currently have a perl script that uses opendir and readdir for a listing
> of files within a certain directory.  however, this just returns the file
> name(s) that are currently present when i run the script.  is there a way of
> getting the file date also?  this script returns back the number of users
> logged into a certain db so i need to know just when they logged in.
> i'm trying to stay away from using system() calls such as dir.
> the script runs on a winnt box and the dir it reads is (i believe) ntfs.
>
> &date;
> system("cls");
> print ("\t[ $date:$time ]\n\n");
> $directory = "z:/some/dir";
> opendir(Dir, $directory) || die ("Could not open $directory.");
> @allFilesWithinDir=readdir(Dir);
>
> foreach $fileNames (@allFilesWithinDir)
> {
>         # only interested in files within specified dir
>         if(-d "$directory/$fileNames"){next}
>         # use escape sequence to print $fileNames in lowercase
>         print ("\L$fileNames\n");
> }
> closedir(Dir);
>
> # date function
> sub date
> {
>  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
>  @months = ("1","2","3","4","5","6","7","8","9","10","11","12");
>  @days = ("Sun","Mon","Tue","Wed","Thur","Fri","Sat");
>         if ($sec < 10) {$sec = "0$sec";}
>         if ($min < 10) {$min = "0$min";}
>         if ($hour < 10) {$hour = "0$hour";}
>         if ($hour > 11) {$ampm = "PM";}
>         if ($hour < 12) {$ampm = "AM";}
>         if ($mday < 10) {$mday = "0$mday";}
>  $millyear = $year + 1900;
>  $date = "@days[$wday] @months[$mon]/$mday/$millyear";
>  $time = "$hour:$min:$sec:$ampm";
>
> tia,
> rick



------------------------------

Date: Wed, 11 Jul 2001 00:23:22 GMT
From: troll@gimptroll.com (TuNNe|ing)
Subject: Re: file date
Message-Id: <3b4bb625.163616213@news>

On Tue, 10 Jul 2001 13:59:20 GMT, "Scaramouche"
<e.quesada@verizon.net> wrote:

[snip]
  is there a way of
>getting the file date also?  
[/snip]

you can use the File::stat  module to get all kinds of info about a
file.

TuNNe|ing
http://www.gimptroll.com


------------------------------

Date: 09 Jul 2001 18:02:25 +0100
From: nobull@mail.com
Subject: Re: File properties with Perl (win32) (I'm a newbie)
Message-Id: <u9g0c69gta.fsf@wcl-l.bham.ac.uk>

"Kjetil Furnes" <banjo@chello.no> writes:

> opendir (TMPFILES, "C:/Temp");
> @files = readdir(TMPFILES);

> foreach $f (@files) {
>  $i{$f} = -S $f };

> It must be something silly, I hope :-)

It is.

> <NEWBIE>

Do not call yourself "newbie" around here.  It is OK for other people
can call you newbie but when people around here refer to themselves as
"newbie" it almost invariably means "not willing to read the manual".

If a program does not work as you expect then look at the manual
entries for all the functions you are using to check that you have
correctly understood what they do.

The second paragraph of the manual entry for readdir() is an explicit
warning about the exact error you have made.

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


------------------------------

Date: Wed, 11 Jul 2001 02:53:08 GMT
From: mike hardy <no_sp@m.for_me.org>
Subject: Re: Filtering mail based on size
Message-Id: <jbu20k42b4.fsf@analog.net>


Nostradamus foretold that on Tue Jul 10 2001, Clinton A. Pierce would write:

> [no mail, hopeless paranoid address munger]
> 
> In article <jb4rsorq4x.fsf@analog.net>,
> 	mike hardy <no_sp@m.for_me.org> writes:
> > I can use Mail::Audit to do everything besides the most important part -
> > determining the size of the message.  
> 
> The manpage for mail audit says that once you have a Mail::Audit object, you
> can call the body method which will return:
> 
> 	Returns a reference to an array of lines in the body
>            of the email.
> 
> Let's say you've got:
> 
> 	$b=$mess->body();
> 
> So now you can say:
> 
> 	if (@$b > 1000) {   # More than 1k lines
> 		$mess->reject("Blah blah blah");
> 	}
> 
> 	for(@$b) { $l+=length }
> 	if ($l > 10000) {  # More than 10k bytes
> 		$mess->reject(Blah blah blah");
> 	}
> 
> 

Thanks!  That's just what I needed to get my script finished.  I had the
'@$' part but didn't know how to use it correctly...

Mike
-- 



------------------------
mhardy_mail@NO_SPAM@yahoo.com

Auntie Em: Hate you, hate Kansas; took the dog - Dorothy


------------------------------

Date: Tue, 10 Jul 2001 17:24:45 -0500
From: "Neil" <neil@alaweb.com>
Subject: forking ChangeNotify's
Message-Id: <tkn06mb4nrr145@corp.supernews.com>

I have a piece of code below that "watches" to see if  a log file on a
certain machine on our network changes size and outputs (to the screen) what
the changes are.
Basically a "poor mans tail -f".

This is great as I *can* output it to  HTML format so I can track this log
from home etc.

However - I want to track several logs and while I *can* write several
scripts - I would like to incorporate all "watching" into one script. I was
thinking if I had a process that "fork"ed each of the watchers - and can
kill them when the main script was called to exit. Each "watcher" is
responsible for carrying out it's own actions (ie creating an HTML page,
sending an e-mail etc.) and resuming watching.

I am on a Win32 system. I have not attempted forking yet - but have read as
much as I can about fork in the docs and several O'Reilly books - I am just
trying to avoid any heartache and lost time before I get there ...LOL

Any ideas about the "best way" to handle this ?

Thanks,
Neil

------------code below -------------------------

require "E:/admin/lib/admin-lib.pl";
use Win32::ChangeNotify;
use Mail::Sendmail;

my (@stat, $beginsize, $endsize, $notify,
        $directory, $file,
        );

$directory = '\\\\chameleon\\admin\\cron';
$file = $directory . '\\cron.log';

print "Monitoring Cron Log on hippo...\n\n";

while (1)        {
        @stat = stat("$file");
        $beginsize=$stat[7];
        $notify = Win32::ChangeNotify->new($directory,0,'LAST_WRITE')
                        or die "$^E";
        $notify->wait or warn "Something failed: $!\n";

        # There has been a change.
        @stat = stat($file);
        $endsize=$stat[7];
        # Did the log change?
        if ($beginsize != $endsize)
                {
                open (CRONLOG, $file);
                seek (CRONLOG, $beginsize,0);
                my $contents = 1;
                while ($contents)
                   {
                   read (CRONLOG, $contents, 1024);
                   print $contents;
                   }
           close (CRONLOG);
        } #  End if
} #  Wend




------------------------------

Date: Tue, 10 Jul 2001 21:09:51 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: forking ChangeNotify's
Message-Id: <3B4BA75F.878EA8E8@earthlink.net>

Neil wrote:
> 
> I have a piece of code below that "watches" to see if  a log file on a
> certain machine on our network changes size and outputs (to the
> screen) what the changes are.  Basically a "poor mans tail -f".
> 
> This is great as I *can* output it to  HTML format so I can track this
> log from home etc.
> 
> However - I want to track several logs and while I *can* write several
> scripts - I would like to incorporate all "watching" into one script.
> I was thinking if I had a process that "fork"ed each of the watchers -
> and can kill them when the main script was called to exit. Each
> "watcher" is responsible for carrying out it's own actions (ie
> creating an HTML page, sending an e-mail etc.) and resuming watching.
> 
> I am on a Win32 system. I have not attempted forking yet - but have
> read as much as I can about fork in the docs and several O'Reilly
> books - I am just trying to avoid any heartache and lost time before I
> get there ...LOL
> 
> Any ideas about the "best way" to handle this ?

Win32 does not support real forking, but does manage to simulate it
pretty durn well.  So if you want to use a forking solution, then go
ahead and do it.

#! perl.exe -w
use strict;
use IO::Select;
for my $filename (@ARGV) {
	if( my $pid = fork ) {
		push @children, $pid;
		next;
	}
	die "Couldn't fork: $!\n" unless defined $pid;
	open my $fh, "<", $filename or
		die "Couldn't open $filename: $!";
	seek $fh, my $size = -s $fh;
	my $select = IO::Select->new $fh;
	while( $select->can_read ) {
		$size += read $fh, my $contents, (-s $fh) - $size;
		print $contents;
	}
	die "Error in select: $!\n";
}
while( -1 != my $pid = wait ) {
	for( 0 .. $#children ) {
		next unless $children[$_] == $pid;
		print "Tail on file $ARGV[$_] died: $?\n";
	}
}

Or, you could use the full functionality of select, and avoid forking:

#! perl.exe -w
use strict;
use IO::Select;

my %size;
my $select;
for my $filename (@ARGV) {
	open my $fh, "<", $filename or
		die "Couldn't open $filename: $!";
	seek $fh, $size{$fh} = -s $fh;
	$select->add $fh;
}
while( my @ready = $select->can_read ) {
	for my $fh (@ready) {
		$size{$fh} += 
			read $_, my $contents, (-s $fh) - $size{$fh};
		print $contents;
	}
}
die "Error in select: $!\n";

-- 
The longer a man is wrong, the surer he is that he's right.


------------------------------

Date: Tue, 10 Jul 2001 19:00:05 GMT
From: "Todd Smith" <todd@designsouth.net>
Subject: ftp script
Message-Id: <VgI27.28063$B5.5969830@news1.rdc1.tn.home.com>

How can I write a script to try to log in to an ftp server for me, and if
there are too many users, wait a few minutes and try again? But the thing
is, if it gets in, I need to have a normal ftp shell and I need it to keep
the connection alive until I check back with the program.




------------------------------

Date: Tue, 10 Jul 2001 10:53:02 +0100
From: Kourosh A Mojar <kmojar@bmjgroup.com>
Subject: fuzzy string comparision?
Message-Id: <3B4AD07E.1ADDCCC0@bmjgroup.com>

dear all,

hi, im a novice perl user as usual! im trying to compare two string
variables in one of my statements allowing for some 5% error margin in
difference (i.e. number of characters, spelling).

a typical string will contain something like "Weight-reducing diets for
control of hypertension in adults"

some one has already pointed me to something called "soundex" and its
perl modules but i could make little sense of this...

i would be grateful for any suggestions and idiot proof guidance as to
what i should be doing. thanking you in advance and for your kind
attention,

kourosh


------------------------------

Date: Tue, 10 Jul 2001 12:36:52 +0100
From: Malte Ubl <ubl@schaffhausen.de>
Subject: Re: fuzzy string comparision?
Message-Id: <3B4AE8D4.FA2E5952@schaffhausen.de>

Kourosh A Mojar schrieb:
> 
> dear all,
> 
> hi, im a novice perl user as usual! im trying to compare two string
> variables in one of my statements allowing for some 5% error margin in
> difference (i.e. number of characters, spelling).

Check out:
http://theoryx5.uwinnipeg.ca/mod_perl/cpan-search?filetype=%20distribution%20name%20or%20description;join=and;arrange=file;download=auto;stem=no;case=clike;site=ftp.funet.fi;age=;distinfo=2094

Bye,
->malte


------------------------------

Date: 10 Jul 2001 10:39:42 GMT
From: ebohlman@omsdev.com (Eric Bohlman)
Subject: Re: fuzzy string comparision?
Message-Id: <9iem1e$2g0$2@bob.news.rcn.net>

Kourosh A Mojar <kmojar@bmjgroup.com> wrote:
> hi, im a novice perl user as usual! im trying to compare two string
> variables in one of my statements allowing for some 5% error margin in
> difference (i.e. number of characters, spelling).

Take a look at the String::Approx module available from CPAN.



------------------------------

Date: Mon, 9 Jul 2001 14:54:37 -0400
From: "Anil Kripalani" <anilk@broden.com>
Subject: Getting Byref Argument
Message-Id: <m1n27.263$S23.162402@news.uswest.net>

Is there some trick to reading a byref argument?  I am making a COM call (to
VB ActiveX DLL) where the second argument is returned (byref).  I can't read
it from a PerlScript call (It's just empty).  Is there anything special I
need to do?

Thanks,
Krip





------------------------------

Date: Tue, 10 Jul 2001 13:27:14 +0200
From: "Kenneth Bruyninckx" <kenneth@akerne-orchids.com>
Subject: Graphviz (was "family tree" generator)
Message-Id: <3b4ae692$0$12223$4d4efb8e@news.be.uu.net>

Hello all,

After a bit more searching I came across Graphviz which would seem to be the
ideal tool to draw "family tree"/organizational charts and the likes.

Which programs/scripts would I use to introduce a background into the graphs
generated by Graphviz and continuing on the same theme how does one add a
bit of text/logo in the generated output ?

Any ideas ?




------------------------------

Date: 11 Jul 2001 02:54:03 GMT
From: shanali@singnet.com.sg (S H A N)
Subject: greping records from file through file - code fix
Message-Id: <slrn9knfrn.15fi.shanali@zoom.mine.nu>

 Hi, the following code fails to run with something like 10Mb of
 shadow stuff. Any suggestions what's wrong here ?

 Thanks

 #!/usr/bin/perl -w

 open (IDS,"ids");
 open (POUT,">shadow.ids");

 while ($ids=<IDS>) {
    chomp($ids);
    open (PWD,"shadow");
    while ($pwd=<PWD>) {
      chomp($pwd);
      @fields = split(/:/,$pwd);
      if ($ids eq $fields[0]) {
         print POUT $pwd,"\n";
      }
    }
    close (PWD);
 }
 close (IDS);    
 close (POUT); 
-- 
---------------------------------
Shan Ali Khan
SingNet Network Operations Centre


------------------------------

Date: 10 Jul 2001 22:04:29 -0500
From: logan@cs.utexas.edu (Logan Shaw)
Subject: Re: greping records from file through file - code fix
Message-Id: <9igfnt$dvk$1@charity.cs.utexas.edu>

In article <slrn9knfrn.15fi.shanali@zoom.mine.nu>,
S H A N <shanali@singnet.com.sg> wrote:
> Hi, the following code fails to run with something like 10Mb of
> shadow stuff. Any suggestions what's wrong here ?

> #!/usr/bin/perl -w
>
> open (IDS,"ids");
> open (POUT,">shadow.ids");
>
> while ($ids=<IDS>) {
>    chomp($ids);
>    open (PWD,"shadow");
>    while ($pwd=<PWD>) {
>      chomp($pwd);
>      @fields = split(/:/,$pwd);
>      if ($ids eq $fields[0]) {
>         print POUT $pwd,"\n";
>      }
>    }
>    close (PWD);
> }
> close (IDS);    
> close (POUT); 

You're reading and parsing the entire "shadow" file once for every
single line in the file "ids".  This is going to take forever, or to be
more precise, the amount of time it will take will be proportional to
the product of the number of lines in the two files.

As long as "shadow" isn't really huge, you'll probably have better
luck with a hash approach:

	# build the hash
	open (SHADOW, "shadow") or die;
	while (<SHADOW>)
	{
	    chomp;

	    /^([^:]+):/;	# extract first field

	    $shadow{$1} = $_;
	}
	close SHADOW;

	open (POUT, ">shadow.ids") or die;
	open (IDS, "ids") or die;

	while ($ids = <IDS>)
	{
	    chomp $ids;

	    if (defined $shadow{$ids})
	    {
		print POUT $shadow{$ids};
	    }
	}

	close IDS;
	close POUT;

Hope that helps.

  - Logan
-- 
my  your   his  her   our   their   _its_
I'm you're he's she's we're they're _it's_


------------------------------

Date: 11 Jul 2001 03:17:16 GMT
From: shanali@singnet.com.sg (S H A N)
Subject: Re: greping records from file through file - code fix
Message-Id: <slrn9knh78.15is.shanali@zoom.mine.nu>

* Logan Shaw <logan@cs.utexas.edu>:
>  In article <slrn9knfrn.15fi.shanali@zoom.mine.nu>,
>  S H A N <shanali@singnet.com.sg> wrote:
> > Hi, the following code fails to run with something like 10Mb of
> > shadow stuff. Any suggestions what's wrong here ?
>  
snip
>  
>  	close IDS;
>  	close POUT;
>  
>  Hope that helps.
>  
>    - Logan

Hi, thanks! worked pretty cool. Thanks for helping out a perl-newbie!

-- 
S H A N


------------------------------

Date: Tue, 10 Jul 2001 01:21:33 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Grouping and sorting
Message-Id: <3B4A90DD.98974C9C@earthlink.net>

twolfmaier@acm.org wrote:
> 
> I have a problem I don't seem to be able to wrap my mind around. I
> need to group hashes based on the starting character of a key value
> and then sort them.
> 
> Let me illustrate this on a example. I need to create a glossary. I
> have an array of hashes containing the terms and descriptions:
> 
> my @glossary = (
>     { 'term' => 'ccc', 'description' => 'ccc description' },
>     { 'term' => 'aaa', 'description' => 'aaa description' },
>     { 'term' => 'bbb', 'description' => 'bbb description' },
>     { 'term' => 'aba', 'description' => 'aba description' }
>     # many more
> );
> 
> I need to group them by alphabetical character and sort them so the
> output would look something like:
> 
> A
> 
> aaa     aaa description
> aba     aba description
> 
> B
> 
> bbb     bbb description
> 
> There are two issues that complicate things:
> 
> 1. Terms might start with accented characters, e.g.,
> 
> A
> 
> aaa     aaa description
> áaa     áaa description
> aba     aba description
> 
> 2. Terms might start with non-alphabetical characters in which case
> they should end up in a bucket called Symbols, e.g.,
> 
> Symbols
> 
> 111     111 description
> "a"     "a" description
> 
> I am stuck on this one. Any help is appreciated. The number of hashes
> is small enough to keep in memory.

my %index;
for my $item ( @glossary ) {
	(my $key = substr $item->{term}, 0, 1) =~ tr
	[¶§ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥PƒáíóúñѪ߶µn]
	[pscueaaaaceeeiiiaaeaaooouuyouclypsaiounnaspun];
	# of course, this depends on your charset.

	# Note that the ß (which looks like a funky B), is a german
	# symbol which is usually translated as "ss"
	# The only places I've seen it is in the names Gauß and Strauß.

	$key = "Symbols" unless $key =~ tr/a-zA-Z/A-ZA-Z/;
	push @{$index{$key}}, $item;
}

for my $letter ( "A" .. "Z" ) {
	print $letter, "\n\n";
	next unless my $coalated = $index{$letter};
	for my $item (sort @$coalated) {
		print $item->{term}, "\t", $item->{description}, "\n";
	}
	print "\n";
}
print "Symbols\n\n";
print $_->[0], "\t", $_->[1], "\n" for sort @{$index{Symbols}};


-- 
The longer a man is wrong, the surer he is that he's right.


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 1275
***************************************


home help back first fref pref prev next nref lref last post