[7509] in Perl-Users-Digest
Perl-Users Digest, Issue: 1135 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Oct 7 02:06:43 1997
Date: Mon, 6 Oct 97 23:00:19 -0700
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Mon, 6 Oct 1997 Volume: 8 Number: 1135
Today's topics:
"cannonical" location of perl binary (Andrew Pimlott)
Re: $x = $y || $z - dangerous assumption? <joegottman@worldnet.att.net>
Re: $x = $y || $z - dangerous assumption? (Damian Conway)
Re: Another Perl vs C question <bholzman@mail.earthlink.net>
Re: chop from left to right (brian d foy)
Re: chop from left to right (Tad McClellan)
Re: Converting to proper case (Tad McClellan)
looking for charity - telnet to port 25 <rama@mae.engr.ucdavis.edu>
Re: need info on SGML parsers (Tad McClellan)
Re: Newbie ques: How to concatenate two strings? (Mike Heins)
Re: Newbie ques: How to concatenate two strings? (Joseph)
Perl on Windows 95 backtick problem (Jim Joyce)
Re: Resetting <FILEHANDLE> (Tad McClellan)
Re: Socket and Command Line Arguments (Tad McClellan)
Sorting values such as 1.1, 1.1.1, 2.1 into order <tony.mcdonald@ncl.ac.uk>
Re: Sorting values such as 1.1, 1.1.1, 2.1 into order <guptas@slip.net>
Re: Sorting values such as 1.1, 1.1.1, 2.1 into order (brian d foy)
Re: Sorting values such as 1.1, 1.1.1, 2.1 into order (Tad McClellan)
Re: Sorting values such as 1.1, 1.1.1, 2.1 into order (Andrew M. Langmead)
Digest Administrivia (Last modified: 8 Mar 97) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 7 Oct 1997 03:07:47 GMT
From: andrew@pimlott.student.harvard.edu (Andrew Pimlott)
Subject: "cannonical" location of perl binary
Message-Id: <slrn63ja4i.2bt.andrew@pimlott.student.harvard.edu>
I remember reading somewhere (in the online documentation or the Camel) that
/usr/bin/perl is the official location of the perl binary (on unix systems).
I can't for the life of me find it now. I'd like to have something to point
to when I tell people to start their scripts with #!/usr/bin/perl . I know
it's used in all the examples, but I seem to remember it being stated
explicitly.
(I've already grepped my perl man files.)
Thanks,
Andrew
--
"These days, you can't throw a tomato out the window without hitting a
college kid who knows and loves Linux."
http://www.ncworldmag.com/ncworld/ncw-08-1997/ncw-08-4995nc.html
------------------------------
Date: Mon, 06 Oct 1997 23:15:18 -0400
From: Joe Gottman <joegottman@worldnet.att.net>
Subject: Re: $x = $y || $z - dangerous assumption?
Message-Id: <61c9nf$qrv@bgtnsc02.worldnet.att.net>
Damian Conway wrote:
>
> damian@cs.monash.edu.au (Me, myself :-) writes:
>
> >Good point. How about this then:
> >
> > sub try ($) { return defined($_[0]) ? \$_[0] : undef }
> >
> > my $x = ${ try shift || try $default };
>
> Oops, I meant:
>
> sub try ($) { return defined($_[0]) ? \$_[0] : \undef }
>
> so that $x gets a proper undef if none of them is defined.
>
> damian
But if shift returned the value 0 then your function would still go on
to
evaluate the $default even though you don't want it to.
--
Joe Gottman
joegottman@nospam.worldnet.att.net
[Remove nospam to reply]
------------------------------
Date: 7 Oct 1997 05:43:57 GMT
From: damian@cs.monash.edu.au (Damian Conway)
Subject: Re: $x = $y || $z - dangerous assumption?
Message-Id: <61ci6t$qvl$1@towncrier.cc.monash.edu.au>
Joe Gottman <joegottman@worldnet.att.net> writes:
>Damian Conway wrote:
>>
>> sub try ($) { return defined($_[0]) ? \$_[0] : \undef }
>>
>> so that $x gets a proper undef if none of them is defined.
>>
>> damian
>But if shift returned the value 0 then your function would still go on
>to evaluate the $default even though you don't want it to.
Damn! Looks like it's better off with the original unreferenced
undef, generating an error if no alternative is defined:
my $x = ${ try shift or try $default or \undef };
Ah well, suitably chastened, I'll get back in the newbies' box for a bit
longer ;-)
damian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
who: Damian Conway email: damian@cs.monash.edu.au
where: Computer Science Dept. web: http://www.cs.monash.edu.au/~damian
Monash University quote: "The best form of self-defence is
Clayton 3168, Australia not being there in the first place"
------------------------------
Date: Sun, 05 Oct 1997 21:53:10 -0400
From: Benjamin Holzman <bholzman@mail.earthlink.net>
To: jaws@atl.mindspring.com
Subject: Re: Another Perl vs C question
Message-Id: <34384486.3910E785@mail.earthlink.net>
[posted & mailed]
John Armsby wrote:
>
> Please forgive this question but I have not read the "answer" so I
> must ask the question...
>
> I have embraced perl to implement cgi scripts with one exception. I
> have a 3-4 meg ascii file which is 'searched' by the user inputing a
> query string which I 'strstr' one line at a time. When there is a
> string match, the script spits back the line in html... This script
> is invoked approximately 2,000 times a day on a sun sparc 20 with 128
> megs of ram. The entire script is probablly only about 300 lines or
> so. If I had written it in Perl, it would probably be a third of the
> size... All the C script does is parse a single input from a form,
> make it lower case, read the 3-4 meg file a line at a time, make each
> line lower case as it reads it, compares the lower case query within
> the line, and spits out html if there is a match anywhere along the
> line.
>
> I recently upgraded the C code with incredible pain and suffering to
> output a simple html table. In perl this would have been trivial.
> In C (since I have become rusty) it was exceedingly unpleasant.
>
> I stuck with the C because I need speed to spit out the html. I
> thought (true or false) that Perl compiling would slow things down. I
True and false. A compiled c program will be much faster on start-up
than a perl script. However, if you're using the apache web server, you
don't have to have your perl cgi scripts recompiled upon each
invocation. Embed a perl interpreter in apache using mod_perl!
http://perl.apache.org/ or
CPAN/modules/by-module/Apache/mod_perl-1.00b2.tar.gz
> also have been afraid that all those Perl compilations by the users
> would put extra pressure on the hard disks. It seems that the C
> script remains in ram... Right now the user starts to see html on his
> browser within a couple of seconds...
I bet you could get this down to a fraction of a second by indexing your
ascii file. This can be done in a completely separate program, and is
probably better done in perl than c. Depending on the nature of your
data, you can probably do something along these lines:
First, create an index of words and their byte-offsets. That is,
create a data structure where each unique word is linked to all the
locations it exists in the file. Like, perhaps, a hash of arrays. You
probably want to ignore words such as 'a', 'the', etc. Write the
results of this out (like: 'word1 45,123,3344,12341,32342')
Second, in your (now persistent, I hope) cgi script, read in this index
at startup and then when you get each query string, take a word in the
string which is in your structure, seek to each possible location in the
data file and read in enough data to determine whether you have a match
or not.
If your data changes frequently, you'll have to regenerate the index
each time (obviously). I know my description was a touch vague, but I
hope it helps. There's MANY, MANY possible optimizations that can be
made, but those are for you and your data to work out...
>
> Are there any comments on this simple script as to whether i should
> rewrite the script in Perl and forsake C or stick to C? Is there a
> technical reason here or does it boil down to what is easiest for me?
>
> John Armsby
Probably whatever gets the job done.
------------------------------
Date: Mon, 06 Oct 1997 23:16:40 -0400
From: comdog@computerdog.com (brian d foy)
Subject: Re: chop from left to right
Message-Id: <comdog-ya02408000R0610972316400001@news.panix.com>
In article <61c18q$h52$1@news.wco.com>, chris@mtnweb.com (Chris Toth) wrote:
>#!/usr/local/bin/perl
>$amount = "\$ 43.38";
>$amount = ~ s/\$//;
>$amount = $amount +1;
>print ($amount);
>
>but when I run it I get:
>
>4294967296
>
>instead of just 43.38
let's try a little experiment to see if we can isolate the problem.
we'll print the value of $amount every time we do somthing to it:
#!/usr/bin/perl
$amount = "\$ 43.38";
print "Before: $amount\n";
$amount = ~ s/\$//;
print "Later: $amount\n";
$amount = $amount +1;
print "Even later: $amount\n";
__END__
which gives the output
Before: $ 43.38
Later: 4294967295
Even later: 4294967296
somewhere around your substitution something goes wacky, so let's look
at that line more closely
$amount = ~ s/\$//;
hmmmm.... there seems to be an added space between the = and the ~,
so we aren't binding $amount to s///. instead, we're subsituting
on $_, which is undefined, so s/// returns 0 since there were no
matches. then, we run into the ~ operator, which flips all the bits
of the number you give it - in this case 0 - turning your 32 zero bits
into 32 one bits which in decimal is 4294967295. this is then
assigned to $amount.
get rid of that extra space and everything should work :)
--
brian d foy <comdog@computerdog.com>
NY.pm - New York Perl M((o|u)ngers|aniacs)* <URL:http://ny.pm.org/>
CGI Meta FAQ <URL:http://computerdog.com/CGI_MetaFAQ.html>
------------------------------
Date: Mon, 6 Oct 1997 23:03:02 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: chop from left to right
Message-Id: <m9cc16.6f2.ln@localhost>
Chris Toth (chris@mtnweb.com) wrote:
: Ok,
: I have a variable called $amount that gets its info from elsewhere and
: and the info it gets always has a $ sign in front of it, but I have to
: strip off the $ and just have the numercal value left, for example, lets
: say that $amount returns $ 43.38 I need to get $amount to return or
: become, just 43.38. To try and figure out how to do this I wrote this
: silly little test script which I thought would work:
: #!/usr/local/bin/perl
Put the -w switch in there.
It will tell you where the problem is...
#!/usr/local/bin/perl -w
ALWAYS use the -w switch.
: $amount = "\$ 43.38";
If you use single quotes, you won't need to backwack the dollar sign:
$amount = '$ 43.38';
: $amount = ~ s/\$//;
: $amount = $amount +1;
Adding a one dollar commission or something there?
: print ($amount);
: but when I run it I get:
: 4294967296
: instead of just 43.38
^^^^^
Eh? 43.38 + 1 = 44.38 ...
: Anyone know what I am doing wrong?
Yes.
You are not using the -w switch.
ALWAYS use the -w switch.
You should have a look at the very first step for debugging perl scripts
given in the perldebug (who'd a thunk it) man page.
ALWAYS use the -w switch.
: Anyone have an elegant way of doing
: what I am trying to do? Examples are most apreciated. thanks ALL
$amount =~ s/\$\s*//;
print ($amount);
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: Mon, 6 Oct 1997 22:49:19 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: Converting to proper case
Message-Id: <vfbc16.sa2.ln@localhost>
Josiah Tinkerton (jtinkerton@hotmail.com) wrote:
: Howdy,
: How does one convert text to proper case?
That depends on what 'proper case' means in your case ;-)
All lower case is proper?
All upper case is proper?
Initial caps is proper?
What is 'proper case' for "mcclellan"?
Give us some data, and tell us what it should like like when it
comes out of the script, and someone will likely write it.
: 1) Yes I checked the FAQ's and the Llama book and
: 2) I searched Deja News for days.
I do not see the very *first place to look* for answers to perl
questions in your list there.
That would be the 'man pages' included with the perl distribution.
They have info on how to do any of the above interpretations of
'proper' (except for that name one ;-)
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: 7 Oct 1997 05:05:44 GMT
From: "Rama Polefka" <rama@mae.engr.ucdavis.edu>
Subject: looking for charity - telnet to port 25
Message-Id: <01bcd2dd$d7e5d3a0$dcaf6fce@caffiend.rely.com>
i am trying to automate a mail flush from a smtp server. in order to do
this, i need to telnet to port 25 and issue a command to start the flush.
thats it.
i am using the activestate version for win32 and have cut and pasted the
following script:
if you see anything glaringly wrong, please give me a pointer if you could.
thanks a bunch
rama polefka
rama@mae.engr.ucdavis.edu
################################################
################################################
################################################
#! \perl95\bin\perl
#
# sends a script to a telnet port
# rp hack
################################################
require 'sock.pl';
require 'telnet.pl';
$timeout = 1;
$hostname = "my.nameserver.com";
$port = 25;
$flush = "etrn#mydomain.com";
#################################################
# open the connection
#
$session = &sock'open($hostname, $port) || die $!;
#################################################
# send the command
#
print $session "$flush\n"; #sends the flush command
#################################################
# quit the telnet session
#
print $session "quit\n";
#################################################
# get any exit messages
#
until (&telnet'eof) {
# print &telnet'read($session, $timeout);
$junk = &telnet'read($session, $timeout);
}
&sock'close($session);
exit (0);
#################################################
# on any error this will cleanly quit the telnet session
#
sub abort {
&sock'close_all;
die "ended unexpectedly, but shut down cleanly\n";
}
------------------------------
Date: Mon, 6 Oct 1997 22:40:11 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: need info on SGML parsers
Message-Id: <ruac16.792.ln@localhost>
brian moseley (brian@criticalpath.net) wrote:
: hi. im designing a "web application framework" using apache with
: mod_perl. the framework uses the concept of "componentry" (thanks for
: the idea, NeXT :) to implement scripted functionality on the page level.
: i'm going to be creating a small page description language (let's call
: it pdl), which i will embed in standard html files. the framework will
: map pdl tags to scripted behavior in corresponding perl scripts.
: i'm wondering what i should use to parse HTML files for pdl tags. upon
: first glance, SGML::SPGrove seems like it should do the trick, but .. i
: am having a difficult time wading through the SP documentation.
Can you just use 'nsgmls' an application built from SP, and included
with the SP distribution?
It generates a very easy-to-parse output (ESIS).
One problem with treating HTML as real SGML is that the major browser
manufacturers do not treat HTML as real SGML.
They do not publish DTDs for their 'extensions', so finding a DTD
to use with pages employing the extensions is problematic.
: ken, is the module in a form that i'll be able to use immediately? you
: note that "there will be a significant number of errors when loading an
: XML or HTML document without a Document Type Definition" .. will this
: render the code unusable? what is your timeline for the additions you
: note in the "FUTURE" section of the README?
: i'm pretty new to the concept of SGML. what are good sources of
: information?
The SGML/XML Page:
http://www.sil.org/sgml
: has anybody out there done something similar to my project
: in perl? are there other parsers that offer functionality competitive
: with SGML::SPGrove?
perlSGML and SGMLS.pm come to mind, though I don't know what SPGrove
does...
: how do i go about defining a pdl that is consistent
: with SGML standards/rules/definitions/whatever and therefore usable with
: whatever parser i select?
There is no easy answer for that one.
Hang out in the SGML newsgroup for awhile comp.text.sgml
Or, if your pdl is truly small, send me email and I'll DTDify it
for you.
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: 7 Oct 1997 02:01:24 GMT
From: mheins@prairienet.org (Mike Heins)
Subject: Re: Newbie ques: How to concatenate two strings?
Message-Id: <61c55k$1ra$1@vixen.cso.uiuc.edu>
Joseph (jglosz@san.rr.com) wrote:
: On 6 Oct 1997 04:57:56 GMT, mheins@prairienet.org (Mike Heins) wrote:
:
: >I know you are not currently a programmer, because no real programmer
: >could miss the concatenation operator in the docs.
: >
:
: What you "know" is wrong. Given this, you might want to question the
: other things you "know."
:
: I *am* a programmer, [snip]
Sez you. I am sorry for your employer, if any, for if this is the
way you learn and interact with people, you must cause more problems than
you solve.
<*plonk*>
--
Regards,
Mike Heins
This post reflects the
opinion of my employer.
------------------------------
Date: Tue, 07 Oct 1997 02:19:16 GMT
From: jglosz@san.rr.com (Joseph)
Subject: Re: Newbie ques: How to concatenate two strings?
Message-Id: <343a92e9.1638348@news-server>
AND THEN THERE SHALL BE CHAOS IN THE STREETS!!!!
You just added your own noise, you dumb twit.
Look at the other messages in this newsgroup. Exactly HOW MANY other
questions are NOT answerable in the "fucking manual?" Maybe three?
So you're saying this newsgroup should be limited to those three
questions?
Still, you're going to get your way; you're going to get only
"really good questions" on this NG from now on, and prevent it from
"going straight to HELL", because I'm out of here. You've just
reinforced my decision to standardize on ActiveX for our intranet.
So, you'll have a few less people polluting your newsgroup, because
we're dropping all perl scripts as soon as practicable. That should
make you all quite happy.
Joseph
PS, please don't reply via email like you did for the last post.
That's the hallmark of a general internet newbie. Nobody likes that.
Post a newsgroup message to the newsgroup. If you have something to
say privately, then you can email it. Don't do both. It's useless
repetition, and while you may enjoy repeating yourself, others don't
enjoy listening to your repetition.
So, post something here in the NG if you like, for your fellow
brethren, because as of now, I am unsubscribed.
As for the rest of you, see ya. Hope you enjoyed yourselves.
On Mon, 6 Oct 1997 17:24:30 -0700, Tom Phoenix <rootbeer@teleport.com>
wrote:
>When you don't RTFM and RTFFAQ before you PYFSQ, you reduce the S/N ratio
>of this NG. Others who see your FSQ tend to post FSQs of their own.
>Newcomers no longer RTFM, they don't RTFFAQ, and soon the whole NG just
>goes straight to H.
------------------------------
Date: Mon, 06 Oct 1997 22:57:26 -0400
From: NAMEjjoyce@DOMAINpaonline.com (Jim Joyce)
Subject: Perl on Windows 95 backtick problem
Message-Id: <NAMEjjoyce-0610972257260001@207.44.25.223>
I've searched the FAQ on Win32 Perl and have come up empty.
I occasionally use backquotes to capture information from a
command into an array using perl. For example:
@licenses = `$apphome/bin/showlicense`;
This works fine on Solaris as well as Windows NT. It also
*usually* works on Windows 95. I have found one system
which, instead of loading the output from the command
into the array, will simply print the information to
the window and leave the array empty.
This particular system is a laptop, if it makes any difference.
Can anyone shed some light on this?
Thanks in advance.
P.S. You may post replies to this group or email me directly
Name | Domain
-----------+-------
jim.joyce | amp.com
jjoyce | paonline.com
--
=====================================================================
Jim Joyce "Gramen artificiosum odi"
jjoyceATpaonlineDOTcom (Latin for: "I hate Astroturf")
(Substitute '@' for AT and '.' for DOT and you're set)
------------------------------
Date: Mon, 6 Oct 1997 22:52:33 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: Resetting <FILEHANDLE>
Message-Id: <1mbc16.sa2.ln@localhost>
bschlank@pacificnet.net wrote:
: I am using a subroutine which sorts a database and writes it to a
: file. I want to able to call it more than once from the same script,
: but I can't figure out how to clear the information in the file handle
: <DATABASES>. I can't just do this:
: <DATABASES> = "";
: , RIGHT? (besides, I tried it and it doesn't work). It keeps CAT-ing
: the whats in the buffer to the second $db_file that I am sorting....
: I checked the PERL Faqs and even (forgive me) bought a QUE book on
: PERL, but I can't fingure it out. Any answers? Please send e-mail to
: bschlank@pacificnet.net or post here. Thanks in advance for your time!
seek ye the seek() function in the perlfunc man page.
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: Mon, 6 Oct 1997 22:20:06 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: Socket and Command Line Arguments
Message-Id: <6p9c16.c72.ln@localhost>
Woody Jin (wjin@cs.uh.edu) wrote:
: I have a client program which uses socket and it shows
: some strange behavior.
: The client program has:
: ... stuff for setting up socket
: while <SOCK> {
^^^^^^
Beep!
Syntax error...
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: Mon, 06 Oct 1997 19:01:17 +0100
From: Tony McDonald <tony.mcdonald@ncl.ac.uk>
Subject: Sorting values such as 1.1, 1.1.1, 2.1 into order
Message-Id: <tony.mcdonald-ya023080000610971901170001@news.ncl.ac.uk>
I really hope someone can help, I'm slowly losing it here.
I have some values in an array;
#!/usr/bin/perl
$files[0] = "10.html";
$files[1] = "1.html";
$files[2] = "1.1.html";
$files[3] = "1.2.html";
$files[4] = "5.html";
$files[5] = "4.1.html";
$files[6] = "4.html";
$files[7] = "10.1.html";
$files[8] = "10.1.1.html";
$files[9] = "1.1.1.html";
$files[10] = "2.html";
@files = sort(@files);
foreach $filename (@files)
{
print "filename - $filename\n";
}
Which gives the following output,
filename - 1.1.1.html
filename - 1.1.html
filename - 1.2.html
filename - 1.html
filename - 10.1.1.html
filename - 10.1.html
filename - 10.html
filename - 2.html
filename - 4.1.html
filename - 4.html
filename - 5.html
What I want is the following
filename - 1.html
filename - 1.1.html
filename - 1.1.1.html
filename - 1.2.html
filename - 2.html
filename - 4.html
filename - 4.1.html
filename - 5.html
filename - 10.html
filename - 10.1.html
filename - 10.1.1.html
It's essentially a table of contents of some documents (I haven't included
all the chapters for brevity).
Any help whatsoever would be welcomed - this has come up to bite us at a
very bad time.
TIA
Tone
-----------------------------------------------
Tony.McDonald@newcastle.ac.uk, DESIRE trainer, Newt user
Dr Tony McDonald.,Computing Service,Newcastle University. Newcastle Upon
Tyne, NE1 7RU.
http://www.netskills.ac.uk/staff/mcdonald/ - Macs, News, Metadata...
------------------------------
Date: Mon, 06 Oct 1997 20:02:15 -0700
From: Sanjeev <guptas@slip.net>
To: Tony McDonald <tony.mcdonald@ncl.ac.uk>
Subject: Re: Sorting values such as 1.1, 1.1.1, 2.1 into order
Message-Id: <3439A637.75D8@slip.net>
Pretty Simple...
replace
> @files = sort(@files);
with
@files = sort {$a <=> $b} @files;
and u're home..
Sanjeev
Tony McDonald wrote:
>
> I really hope someone can help, I'm slowly losing it here.
>
> I have some values in an array;
> #!/usr/bin/perl
>
> $files[0] = "10.html";
> $files[1] = "1.html";
> $files[2] = "1.1.html";
> $files[3] = "1.2.html";
> $files[4] = "5.html";
> $files[5] = "4.1.html";
> $files[6] = "4.html";
> $files[7] = "10.1.html";
> $files[8] = "10.1.1.html";
> $files[9] = "1.1.1.html";
> $files[10] = "2.html";
>
> @files = sort(@files);
>
> foreach $filename (@files)
> {
> print "filename - $filename\n";
> }
>
> Which gives the following output,
>
> filename - 1.1.1.html
> filename - 1.1.html
> filename - 1.2.html
> filename - 1.html
> filename - 10.1.1.html
> filename - 10.1.html
> filename - 10.html
> filename - 2.html
> filename - 4.1.html
> filename - 4.html
> filename - 5.html
>
> What I want is the following
> filename - 1.html
> filename - 1.1.html
> filename - 1.1.1.html
> filename - 1.2.html
> filename - 2.html
> filename - 4.html
> filename - 4.1.html
> filename - 5.html
> filename - 10.html
> filename - 10.1.html
> filename - 10.1.1.html
>
> It's essentially a table of contents of some documents (I haven't included
> all the chapters for brevity).
>
> Any help whatsoever would be welcomed - this has come up to bite us at a
> very bad time.
> TIA
> Tone
>
> -----------------------------------------------
> Tony.McDonald@newcastle.ac.uk, DESIRE trainer, Newt user
> Dr Tony McDonald.,Computing Service,Newcastle University. Newcastle Upon
> Tyne, NE1 7RU.
> http://www.netskills.ac.uk/staff/mcdonald/ - Macs, News, Metadata...
------------------------------
Date: Mon, 06 Oct 1997 23:49:35 -0400
From: comdog@computerdog.com (brian d foy)
Subject: Re: Sorting values such as 1.1, 1.1.1, 2.1 into order
Message-Id: <comdog-ya02408000R0610972349350001@news.panix.com>
In article <3439A637.75D8@slip.net>, guptas@slip.net wrote:
>Pretty Simple...
it's more tricky than it appears...
>replace
>
>> @files = sort(@files);
>
>with
>
>@files = sort {$a <=> $b} @files;
>
>and u're home..
maybe you are at home, but using your suggestion the poster is
probably still at work...
[n.b. please see original article for description of problem - it's
a bit long]
i wonder if you tested your suggestion - it doesn't work:
#!/usr/bin/perl
@files= qw(10.html
1.html
1.1.html
1.2.html
5.html
4.1.html
4.html
10.1.html
10.1.1.html
1.1.1.html
2.html);
@files = sort {$a <=> $b} @files;
$" = "\n";
print "@files\n";
__END__
gives the output in numberical order, which still does not sort into
the Table of Contents order requested:
1.html
1.1.1.html
1.1.html
1.2.html
2.html
4.html
4.1.html
5.html
10.html
10.1.1.html
10.1.html
however, if we add a bit more to the comparison so that when it tries
to compare a number to a letter it sorts by ASCII value rather than
numerical value, we get what the original poster requested:
#!/usr/bin/perl
@files= qw(10.html
1.html
1.1.html
1.2.html
5.html
4.1.html
4.html
10.1.html
10.1.1.html
1.1.1.html
2.html);
# notice the $a and $b are reversed in the second comparison.
# digits are lower on the ASCII table, but we want them to
# be sorted ahead of alphabetic characters
@files = sort {$a <=> $b || $b cmp $a} @files;
$" = "\n";
print "@files\n";
__END__
which gives the desired output:
1.html
1.1.html
1.1.1.html
1.2.html
2.html
4.html
4.1.html
5.html
10.html
10.1.html
10.1.1.html
--
brian d foy <comdog@computerdog.com>
NY.pm - New York Perl M((o|u)ngers|aniacs)* <URL:http://ny.pm.org/>
CGI Meta FAQ <URL:http://computerdog.com/CGI_MetaFAQ.html>
------------------------------
Date: Mon, 6 Oct 1997 22:16:38 -0500
From: tadmc@flash.net (Tad McClellan)
Subject: Re: Sorting values such as 1.1, 1.1.1, 2.1 into order
Message-Id: <mi9c16.c72.ln@localhost>
Tony McDonald (tony.mcdonald@ncl.ac.uk) wrote:
: I really hope someone can help, I'm slowly losing it here.
: I have some values in an array;
: #!/usr/bin/perl
Even 'examples' should have the -w switch...
[ snip code ]
: Which gives the following output,
: filename - 1.1.1.html
: filename - 1.1.html
: filename - 1.2.html
: filename - 1.html
: filename - 10.1.1.html
: filename - 10.1.html
: filename - 10.html
: filename - 2.html
: filename - 4.1.html
: filename - 4.html
: filename - 5.html
: What I want is the following
: filename - 1.html
: filename - 1.1.html
: filename - 1.1.1.html
: filename - 1.2.html
: filename - 2.html
: filename - 4.html
: filename - 4.1.html
: filename - 5.html
: filename - 10.html
: filename - 10.1.html
: filename - 10.1.1.html
: It's essentially a table of contents of some documents (I haven't included
: all the chapters for brevity).
: Any help whatsoever would be welcomed - this has come up to bite us at a
: very bad time.
----------------------------
#!/usr/bin/perl -w
$files[0] = "10.html";
$files[1] = "1.html";
$files[2] = "1.1.html";
$files[3] = "1.2.html";
$files[4] = "5.html";
$files[5] = "4.1.html";
$files[6] = "4.html";
$files[7] = "10.1.html";
$files[8] = "10.1.1.html";
$files[9] = "1.1.1.html";
$files[10] = "2.html";
foreach $filename (sort hierarchically @files)
{
print "filename - $filename\n";
}
# this will prove to be pretty slow if you have a large list...
sub hierarchically {
my(@anums) = $a =~ /(\d+)\./g; # get the number parts
my(@bnums) = $b =~ /(\d+)\./g;
my $i;
for ($i=0; defined($anums[$i]) && defined($bnums[$i]); $i++) {
return $anums[$i] <=> $bnums[$i] unless $anums[$i] eq $bnums[$i];
}
return defined($anums[$i]) ? 1 : -1;
}
----------------------------
--
Tad McClellan SGML Consulting
tadmc@flash.net Perl programming
Fort Worth, Texas
------------------------------
Date: Tue, 7 Oct 1997 05:22:45 GMT
From: aml@world.std.com (Andrew M. Langmead)
Subject: Re: Sorting values such as 1.1, 1.1.1, 2.1 into order
Message-Id: <EHo1Ly.5n0@world.std.com>
Tony McDonald <tony.mcdonald@ncl.ac.uk> writes:
>What I want is the following
>filename - 1.html
>filename - 1.1.html
>filename - 1.1.1.html
>filename - 1.2.html
>filename - 2.html
>filename - 4.html
>filename - 4.1.html
>filename - 5.html
>filename - 10.html
>filename - 10.1.html
>filename - 10.1.1.html
>It's essentially a table of contents of some documents (I haven't included
>all the chapters for brevity).
Sort can take a optional "comparison subroutine". See the entry for
sort in the perlfunc man page or the FAQ <URL:http://www.perl.com/
CPAN/doc/manual/html/pod/perlfaq4/
How_do_I_sort_an_aray_by_anyth.html> for details.
The trick to doing it efficiently is to break the items you want to
sort into their individual components first, save that data, and refer
to that data in your sort comparison. What makes this case unusual is
that there are a varying number of components that need to be checked
to determine sorting order for each element.
Maybe something like this:
# break each file name into its subsections
for $file (@files) {
s/\.html$//;
push @version, [ split /\./, $file ];
}
# create a list of indices. Pass them to sort which will compare
# them according to the by_version subroutine. Use the order
# returned by sort to get a slice of the @files array, and
# get the files in the new order.
@files = @files[ sort by_version 0 .. $#files ];
foreach $filename (@files) {
print "filename - $filename\n";
}
sub by_version {
# determine the maximum number subsections
my $max = $#{$version[$a]} > $#{$version[$b]} ?
$#{$version[$a]} : $#{$version[$b]};
# for each parallel subsection of each element, as soon
# as one subsection is greater, delcare its element
# as being greater.
my $i;
for $i ( 0 .. $max) {
my $result = $version[$a][$i] <=> $version[$b][$i];
return $result if $result;
}
}
--
Andrew Langmead
------------------------------
Date: 8 Mar 97 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 8 Mar 97)
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.misc (and this Digest), send your
article to perl-users@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.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
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 V8 Issue 1135
**************************************