[19895] in Perl-Users-Digest
Perl-Users Digest, Issue: 2090 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Nov 8 00:10:44 2001
Date: Wed, 7 Nov 2001 21:10:11 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <1005196211-v10-i2090@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Wed, 7 Nov 2001 Volume: 10 Number: 2090
Today's topics:
playing WAV file on unix and windows? (winter7)
Re: playing WAV file on unix and windows? <tony_curtis32@yahoo.com>
reg ex <troyr@vicnet.net.au>
Re: reg ex (Garry Williams)
Re: Serving HTML images <goldbb2@earthlink.net>
Re: SQLPLUS via Perl (Garry Williams)
Re: SQLPLUS via Perl <robsjobs@hotmail.com>
Re: stripping garbage from head of file (Garry Williams)
Re: Sucking in /etc/passwd <slytobias@home.com>
Re: Sucking in /etc/passwd <mgjv@tradingpost.com.au>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 7 Nov 2001 19:14:34 -0800
From: winter7@e-mailanywhere.com (winter7)
Subject: playing WAV file on unix and windows?
Message-Id: <fb7341b.0111071914.5c0886c3@posting.google.com>
How do I play .wav file on both unix and windows?
I'm not going to play a music, I just want to play simple and small(about 30k)
wav file.
It's ok if it sounds little different on another platform.
Thanks for any help..
------------------------------
Date: Wed, 07 Nov 2001 21:46:45 -0600
From: Tony Curtis <tony_curtis32@yahoo.com>
Subject: Re: playing WAV file on unix and windows?
Message-Id: <871yj9zzyy.fsf@limey.hpcc.uh.edu>
>> On 7 Nov 2001 19:14:34 -0800,
>> winter7@e-mailanywhere.com (winter7) said:
> How do I play .wav file on both unix and windows? I'm
> not going to play a music, I just want to play simple
> and small(about 30k) wav file. It's ok if it sounds
> little different on another platform.
And your perl question/issue is...?
--
Oh! I've said too much. Smithers, use the amnesia ray.
------------------------------
Date: Thu, 8 Nov 2001 14:54:11 +1100
From: "tez" <troyr@vicnet.net.au>
Subject: reg ex
Message-Id: <2onG7.2529$E81.74705@ozemail.com.au>
Hi Guys,
I have the following string
my $test="www.vicnet.net.au check out this link www.vicnet.net.au it could
be http://www.vicnet.net.au";;
and a regex which follows:
$test=~s/[^\/]www*\b/ http:\/\/www$1/gi;
what i want to happen..is if it finds www i want it to add http:// in front
of it.
But..if http:// is already in front of www then don't do anything.
My above regex doesn't quite do that exactly..anyone have any ideas
TIA
troy
------------------------------
Date: Thu, 08 Nov 2001 04:53:09 GMT
From: garry@ifr.zvolve.net (Garry Williams)
Subject: Re: reg ex
Message-Id: <slrn9uk3tl.qv.garry@zfw.zvolve.net>
On Thu, 8 Nov 2001 14:54:11 +1100, tez <troyr@vicnet.net.au> wrote:
> I have the following string
>
> my $test="www.vicnet.net.au check out this link www.vicnet.net.au it could
> be http://www.vicnet.net.au";;
>
> and a regex which follows:
Actually, this is a substitute operator. It contains a regular
expression and a substitution string.
> $test=~s/[^\/]www*\b/ http:\/\/www$1/gi;
You're close. A few problems and the fix:
You have Leaning Toothpick Syndrome (LTS). :-) Choose another quoting
character for match and substitute operators that contain slashes. It
makes then easier to read.
The regex finds any non-slash character, followed by "ww", followed by
0 or 1 "w" characters, followed by a word boundary. The [^...] is a
negative character class. (Note that the inclusion of [^/] forces
*some* character to be in front of "ww". Thus it will fail when the
"ww" is at the begining of a string unless the "some character" is
"w". Is that why you ask for an optional "w" after the "ww"?)
The substitute replaces all of that with one space followed by the
string "http://www" followed by ... uh, we don't know because the
value of $1 was not set by this statement. It may be set due to a
previous match; it may not be set.
See the perlre manual page for an explanation of (maybe) quantifiers
and capturing parentheses.
> what i want to happen..is if it finds www i want it to add http:// in front
> of it.
> But..if http:// is already in front of www then don't do anything.
>
> My above regex doesn't quite do that exactly..anyone have any ideas
Enable warnings. (It may have given you a hint about an unitialized
variable in the statement above.)
See the perlre manual page for an explanation of look-behind
operators.
$test =~ s#(?<!http://)\bwww\b# http://www#g;
Match any occurrence of "www" surrounded by word boundaries that does
*not* follow "http://". Substitute with a space followed by
"http://www".
--
Garry Williams
------------------------------
Date: Wed, 07 Nov 2001 22:05:52 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Serving HTML images
Message-Id: <3BE9F68F.B9EACBB0@earthlink.net>
Maarten wrote:
>
> Using perl I'm not sure whether this is the right group to ask, but
> anyway: does anybody know how to get a browser to not load a image
> from the cache but from the server instead while using the html IMG
> tag?
>
> Simply setting the last-update header doesn't seem to suffice,
> because the browser doesn't seems look at the header if an obsolete
> (dynamically served) image of the same name can be found in the
> cache.
Have the image loaded from a cgi, and put in the cgi's headers "pragma:
no-cache"
Something like this:
#!/usr/local/bin/perl -wT
# imageloader.cgi
# invoke as http://foo.bar.com/cgi-bin/imageloader.cgi/foo.gif
my ($file) = $ENV{PATH_EXT} =~ m[^([^/]*)\z];
my $dir = "/home/me/myimages/foo/";
unless( open FILE, "<", $dir . $file ) {
print "Status: 404 Not found\n";
print "Content-type: text/plain\n\n";
print "Sorry, can't find $file on this server.\n"
exit;
}
{ local $| = 1;
# Because *these* newlines need to have their \n
# translated into the system dependent newline sequence,
# STDOUT must be in textmode at this time. Since
# some perls don't flush the filehandle when we change
# from textmode to binmode, we need to flush before
# changing STDOUT to binmode. Since perl doesn't provide
# an explicit flush, I just set autoflush when printing
# the cgi headers.
print "Content-type: image/gif\n";
print "Pragma: no-cache\n"; # <-- this line prevents caching.
print "Content-length: ", -s FILE, "\n";
print "\n";
}
binmode STDOUT;
binmode FILE;
print while sysread FILE, $_, 8192;
exit;
--
Klein bottle for rent - inquire within.
------------------------------
Date: Thu, 08 Nov 2001 02:47:41 GMT
From: garry@ifr.zvolve.net (Garry Williams)
Subject: Re: SQLPLUS via Perl
Message-Id: <slrn9ujsid.qv.garry@zfw.zvolve.net>
On 7 Nov 2001 09:14:43 -0800, John Menke <jmenke@scsnet.csc.com> wrote:
> I need to execute a script designed for SQLPLUS in Perl and return the
> output of the script back into the perl environment (meaning I want to
> examine the output from perl)
>
> I have searched the archives and the best advice I could come up with
> is:
>
> ------------------------------------------
> my ($sqlinput) = "c:\\aaa\\fragment1.sql";
> my ($sqloutput) = "c:\\aaa\\test.lst";
> open (SQLPLUS, "|sqlplus -S username/password \@$sqlinput |")
> or die "cannot open sqlplus";
This is actually a FAQ if you really want to write and read to this
program. See the perlfaq8 manual page, "How can I open a pipe both to
and from a command?".
The bottom line is that the open() above doesn't do what you seem to
intend. If you have to read and write to a another process, use
IPC::Open2. The perlipc manual page also discusses this.
If what you really intended is to only read the output of the command,
the second parameter of the open() is incorrect and you should remove
the `|' from the beginning of the string.
BTW, it's good that you check the result of an open(). It's bad that
you omit $! -- the reason for a failure -- from your message. You
also should always check the result of a close on a pipe, because
that's where most errors will be reported. Be sure to read about what
ways those errors are reported in the close() section of the perlfunc
manual page. Sometimes you need to print $? instead of $!.
--
Garry Williams
------------------------------
Date: Thu, 08 Nov 2001 04:00:59 GMT
From: "Rob" <robsjobs@hotmail.com>
Subject: Re: SQLPLUS via Perl
Message-Id: <%rnG7.13295$Yb.2563890@typhoon.tampabay.rr.com>
> my ($sqlinput) = "c:\\aaa\\fragment1.sql";
^ ^
DUMP the ()'s, they'll get in the way since the other side is not an
array.
> my ($sqloutput) = "c:\\aaa\\test.lst";
^ ^
DUMP the ()'s, they'll get in the way since the other side is not an
array.
> open (SQLPLUS, "|sqlplus -S username/password \@$sqlinput |")
^
Do you really need a pipe here?
> or die "cannot open sqlplus";
(as noted earlier, add $! to the die's so you see why they die)
__________________________________
You may be better off using the "spool" command
within SQLPLUS and doing some of the other normal
operations such as:
-- CONTENTS OF SELECT_ALL_FROM_TABLE.SQL
set feedback off
set echo off
set heading off
set pages 0
spool all_from_table.lst
select * from table t
/
spool off;
exit;
-- END OF CONTENTS
By using the spool command as listed above, SQLPLUS will create the file and
put the output into it for you. This cuts down your perl code to two lines:
my $sqlin = "select_all_from_table.sql";
system("sqlplus.exe", "username/password@sid","\@$sqlin")
or die "system for sqlplus failed $!\n";
------------------------------
Date: Thu, 08 Nov 2001 03:32:47 GMT
From: garry@ifr.zvolve.net (Garry Williams)
Subject: Re: stripping garbage from head of file
Message-Id: <slrn9ujv6v.qv.garry@zfw.zvolve.net>
On Thu, 08 Nov 2001 01:48:06 GMT, nick.alexander
<nick.alexander@verizon.net> wrote:
> i'm new to perl, and realize that i don't understand alot. please help if
> you can.
>
> i have a text file that when created will always have a string of garbage at
> its head. i want to strip the garbage from the file.
[ snip ]
> the 'good' part of the file always starts with '<datafile>', so i thought if
> i had the line, i could substitute the garbage with an empty string . but i
> can't figure out how to write it . . .
>
> $_ = s!/<xml>//; #doesn't seem to work ???
I guess that "doesn't seem to work ???" means won't even compile.
Maybe you meant to type
$_ = s/<xml>//;
but even though that will compile, it's probably not what you
intended. I get the feeling I'm debugging a typing error here instead
of looking at actual code you've tried and then copy/pasted into your
post. Am I right?
Well, I'll bite...
That first substitutes nothing for the string `<xml>' in the $_
variable and assigns the *result* of the substitute to $_ (replacing
the just substituted string). The *result* of a substitute operation
(see the perlop manual page, "s/PATTERN/REPLACEMENT/egimosx") is the
number of substitutions made (maximum of one here since /g wasn't
used) or false, if the match failed. If I understand what you think
your data looks like, that would change the first line to a 1 and the
subsequent lines to false (either "", 0, "0" or undef). probably not
what you intended.
Maybe you meant
$_ =~ s/<xml>//;
which is the same as
s/<xml>//;
instead.
But that *removes* part of what you seem to want to preserve.
Assumptions.
1. Only the first line needs altering.
2. All characters starting at the beginning of the first line up to,
but not including the string `<datafile>', should be deleted.
Try this:
#!/usr/bin/perl -w
use strict;
$_ = <>;
s/^.*(<datafile>)/$1/;
print;
print while <>;
Now use it like this:
$ perl strip input.file > output.file
Or maybe you'd like the one-liner:
$ perl -wpe 'BEGIN{$_=<>;s/^.*(<datafile>)/$1/;print}' input > output
--
Garry Williams
------------------------------
Date: Thu, 08 Nov 2001 03:21:32 GMT
From: David Sletten <slytobias@home.com>
Subject: Re: Sucking in /etc/passwd
Message-Id: <3BEA0767.5000204@home.com>
It's considered poor form for map to cause side-effects. This is not
really an issue perhaps when reading from a file where you are just
tossing the original list away, but keep it in mind. The idea is that
mapping is a mathematical notion where the map doesn't affect the
domain. In other words, the function f(x) = 2x + 4 doesn't 'do' anything
to the number 7 when you evaluate f(7). Likewise, when you encounter a
map in code you should expect to see a new list generated from the input
list without having the original list altered.
Anyway, back to your question...
In order to create a hash of lists with usernames as keys do this:
use strict;
open(PW, '/etc/passwd');
my %pwFile = map { chomp(my $line = $_); my @fields = split(/:/, $line);
shift(@fields), [@fields] } <PW>;
close(PW);
foreach (sort(keys(%pwFile))) {
print("$_\t", join(", ", @{$pwFile{$_}}), "\n");
}
You may also want to investigate the getpwent() function.
For example:
my %pwFile;
while ( my @fields = getpwent() ) {
$pwFile{shift(@fields)} = [@fields];
}
Note that you may get some extra fields with the second version. Check
perldoc -f getpwent.
David Sletten
Rob wrote:
> I've gone back through the past postings and seen plenty of examples
> showing how to pull /etc/passwd in a single into a hash with a single
> "map" statement, and most look about like my version:
> %pwFile = map { split(/:/, $_, 2) } (<PW>);
>
> This has the following two problems with my app:
> 1) Lines aren't "chomp"ed.
> 2) What I'd really like is a HOL (hash of lists)
>
> For now I'm using a loop. This is actually OK, and if I wasn't so
> stubburn I'd leave it there. This is one of those puzzle type things,
> however, and I know I'm not going to be able to leave it alone until
> I've figured it out.
>
> My current loop looks like this:
> for (<PASSWD>)
> {
> chomp($_);
> ($key, @pwInfo) = split(/:/, $_);
> $pwFile{$key} = [ @pwInfo ];
> }
>
> Works, but it seems like there should be an easy way to get the same
> thing with a single split. Ideas?
>
> Thanks,
>
> Rob
>
------------------------------
Date: Thu, 08 Nov 2001 03:55:26 GMT
From: Martien Verbruggen <mgjv@tradingpost.com.au>
Subject: Re: Sucking in /etc/passwd
Message-Id: <slrn9uk0ht.1on.mgjv@verbruggen.comdyn.com.au>
On Wed, 07 Nov 2001 15:42:59 -0700,
Rob <XSPAMmagicrob@newsguy.com> wrote:
> I've gone back through the past postings and seen plenty of examples
> showing how to pull /etc/passwd in a single into a hash with a single
> "map" statement, and most look about like my version:
> %pwFile = map { split(/:/, $_, 2) } (<PW>);
>
> This has the following two problems with my app:
> 1) Lines aren't "chomp"ed.
> 2) What I'd really like is a HOL (hash of lists)
Maybe something like:
my %users = map { chomp; my ($u, @u) = split /:/; $u, \@u } <PASSWD>;
or if you want to save a variable:
my %users = map { chomp; my @u = split /:/; shift @u, \@u } <PASSWD>;
But I'd probably do it with a while loop anyway, simply because I tend
to like to process text files line by line, even if they are almost
guaranteed to be small. It's also more readable. One-liners can be
neat, but if you have to force them, they hardly ever are beneficial
to the clarity of your code.
BTW, are you aware of the getpwent function?
my %users;
while (my @user = getpwent())
{
$users{shift @user} = \@user;
}
This is independent of the particular format of your /etc/passwd on
your system. Another benefit is that this will also work for user
accounts that aren't in your /etc/passwd (e.g from NIS or LDAP). This
makes the code a lot more portable.
And if you use User::pwent, you may not need (or want) your hash of
array references at all anymore. The question is a littlebit what you
actually want to do with these data once you have it read in. If you
need to do something for each user account, then the getpwent function
will do fine. If you need to look up users by name, then the getpwnam
function will do fine. I suspect that you really don't need to read
everything into a hash, but you were simply unaware of the getpw*
functions.
Martien
--
|
Martien Verbruggen | Unix is user friendly. It's just
Trading Post Australia Pty Ltd | selective about its friends.
|
------------------------------
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 2090
***************************************