Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Need help with Perl

198 views
Skip to first unread message

Tim A. Grunwald

unread,
Jan 24, 1990, 10:53:06 PM1/24/90
to

I have just begun to use Perl, but I already realize
that it is a very powerful programming language.

I would apreciate any suggestions on how to solve the
following problem.

I need to parse a template file substituting numbers
found in another file.

Template file might look like this:

leading junk
(variable,1)=0.0
(variable,2)=0.0
(variable,3)=0.0
trailing junk

The file with numbers might look like this:

.023431
-2.3432
489.000001

Output file should look like this:

leading junk
(variable,1)=.023431
(variable,2)=-2.3432
(variable,3)=489.000001
trailing junk


I will try this on my own, but would apreciate pointers on the
art of Perl proggramming.


Tim Grunwald
Federal Reserve Board, Washington, DC, 20551
uucp: uunet!fed!m1tag00 internet: m1t...@fed.frb.gov
--
Tim Grunwald
Federal Reserve Board, Washington, DC, 20551
uucp: uunet!fed!m1tag00 internet: m1t...@fed.frb.gov
Tim Grunwald
Federal Reserve Board, Washington, DC, 20551
uucp: uunet!fed!m1tag00 internet: m1t...@fed.frb.gov

Piet van Oostrum

unread,
Jan 26, 1990, 7:18:26 AM1/26/90
to
In article <1990Jan25....@iwarp.intel.com>, merlyn@iwarp (Randal Schwartz) writes:
`
`#!/usr/bin/perl
`open(SECOND,"second") || die "Cannot open second ($!)";
`@nums = grep(chop, <SECOND>); # how's that for fast? Just thought of that
^^^^^^^^^^^^^^^^^^
`
`open(FIRST...
`print grep(s/^(\(variable,\d+\)=).*/$1 . shift(@nums)/e || 1, <FIRST>);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I was very surprised to see that, and didn't believe it would work until I
tried it myself. The documentation of grep says:

grep(EXPR,LIST)

Evaluates EXPR for each element of LIST (locally setting $_ to each element)
and returns the array value consisting of those elements for which the
expression evaluated to true.

It appears that grep does NOT return an array consisting of (some) original
values of LIST, but rather an array consisting of $_ values after
evaluating EXPR.

So the following gives you an array of squares:

print grep ($_=$_**2, 1..10)

I find this a nice feature but it is not according to the documentation.
Or is it a BUG?
--
Piet* van Oostrum, Dept of Computer Science, Utrecht University,
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands.
Telephone: +31-30-531806 Uucp: uunet!mcsun!hp4nl!ruuinf!piet
Telefax: +31-30-513791 Internet: pi...@cs.ruu.nl (*`Pete')

Randal Schwartz

unread,
Jan 25, 1990, 12:16:30 PM1/25/90
to
In article <5...@mqcs2.fed.FRB.GOV>, m1tag00@fed (Tim A. Grunwald) writes:
| I have just begun to use Perl, but I already realize
| that it is a very powerful programming language.

[good, another convert, and potential sale for the book. :-]

| I need to parse a template file substituting numbers
| found in another file.
|
| Template file might look like this:
|
| leading junk
| (variable,1)=0.0
| (variable,2)=0.0
| (variable,3)=0.0
| trailing junk
|
| The file with numbers might look like this:
|
| .023431
| -2.3432
| 489.000001
|
| Output file should look like this:
|
| leading junk
| (variable,1)=.023431
| (variable,2)=-2.3432
| (variable,3)=489.000001
| trailing junk

Hmm. This spec is fairly incomplete. If you just want to replace the
zeroes with successive values from the second file, try this:

#!/usr/bin/perl
open(SECOND,"second") || die "Cannot open second ($!)";
@nums = grep(chop, <SECOND>); # how's that for fast? Just thought of that

close(SECOND);
# @nums now has all the numbers from the second file. Snip them onto the first
open(FIRST, "first") || die "Cannot open first ($!)";
while (<FIRST>) {
# if the line matches the pattern, insert the number:
s/^(\(variable,\d+\)=).*/$1 . shift(@nums)/e;
print;
}
close(FIRST);

Okay, it's cryptic, but it's fast. But wait, you could optimize the
heck out of it, and make it "write-only" code, by changing the second
loop to:

open(FIRST...
print grep(s/^(\(variable,\d+\)=).*/$1 . shift(@nums)/e || 1, <FIRST>);

close(FIRST);

Now *there's* a tight loop! Okay, only for us crazy Perl hackers.
Weird weird weird. I think I'd better have my morning tea before I
program in Perl again today.

Just another Perl hacker,
--
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III |
| mer...@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

Randal Schwartz

unread,
Jan 26, 1990, 1:14:33 PM1/26/90
to
In article <23...@ruuinf.cs.ruu.nl>, piet@cs (Piet van Oostrum) writes:
| It appears that grep does NOT return an array consisting of (some) original
| values of LIST, but rather an array consisting of $_ values after
| evaluating EXPR.
|
| So the following gives you an array of squares:
|
| print grep ($_=$_**2, 1..10)
|
| I find this a nice feature but it is not according to the documentation.
| Or is it a BUG?

Well, it never occurred to me that it was possibly not documented, so
I hope it becomes a FEATURE and not a BUG.

By the way, I cannot take credit for discovering this use of grep().
Someone else on the net sent me some code, which I challenged as you
did, until I verified that it worked.

This is really a neat use of a new tool. You can both manipulate
elements, and remove them, by fiddling with $_ and the return value of
the expression.

Or, consider:

grep(&foo($_), @somearray)

to call &foo for each element of the array. Neat, huh? This ranks
right up there with:

s/./&bar($&)/ge;

to call &bar for each character of a string. Cool. (Disclaimer:
destructive side effect about for that last one. Do not try unless
you know what you're doing...)

Just another Perl hacker trying to make Perl look like lisp, :-)

Larry Wall

unread,
Jan 26, 1990, 5:24:26 PM1/26/90
to
In article <23...@ruuinf.cs.ruu.nl> pi...@cs.ruu.nl (Piet van Oostrum) writes:
: In article <1990Jan25....@iwarp.intel.com>, merlyn@iwarp (Randal Schwartz) writes:
: It appears that grep does NOT return an array consisting of (some) original

: values of LIST, but rather an array consisting of $_ values after
: evaluating EXPR.
:
: So the following gives you an array of squares:
:
: print grep ($_=$_**2, 1..10)
:
: I find this a nice feature but it is not according to the documentation.
: Or is it a BUG?

Let's call it an accidental feature. :-)

The above is actually a bit dangerous to say, because it will only work
the first two times you call it. The third time you'll find you're printing
out cubes, the fourth time fourth powers, etc. That's because the $_ you're
playing with is actually a reference to whatever array you passed in on
the right. So you have to be a bit careful when modifying non-lvalues.

(The reason it doesn't modify 1..10 the first time you call it is that it
gets optimized into an array value during the first evaluation, so the
second call modifies the array value in place. If you said

print grep ($_ = $_ ** 2, 1,2,3,4,5,6,7,8,9,10);

then it would be modified on the first call.)

But I'll see if any sane documentation can be produced for this "feature".
I hope you don't all turn into one of those "grep nuts" like Randall. If
I'm not careful, he'll reduce all my examples to one-liners, and the book
will be 23 pages long.

Larry

Randal Schwartz

unread,
Jan 26, 1990, 8:21:11 PM1/26/90
to
In article <69...@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax (Larry Wall) writes:
| The above is actually a bit dangerous to say, because it will only work
| the first two times you call it. The third time you'll find you're printing
| out cubes, the fourth time fourth powers, etc. That's because the $_ you're
| playing with is actually a reference to whatever array you passed in on
| the right. So you have to be a bit careful when modifying non-lvalues.

Aha! So that's why I had to make a copy of the array for one of my
programs! I'm actually modifying the original array. Hmmm... this
is sorta dangerous.

| But I'll see if any sane documentation can be produced for this "feature".
| I hope you don't all turn into one of those "grep nuts" like Randall. If

=======
ahem! Has it been that long since you saw my name spelled *properly*?

| I'm not careful, he'll reduce all my examples to one-liners, and the book
| will be 23 pages long.

No, it'll be ($i=0,grep($i++, @fullpagetext),$i) pages long. :-)

Just another Perl hacker (and "grep nut" :-),

Jan Dj{rv

unread,
Jan 30, 1990, 4:14:12 PM1/30/90
to
In article <23...@ruuinf.cs.ruu.nl> pi...@cs.ruu.nl (Piet van Oostrum) writes:
:
:It appears that grep does NOT return an array consisting of (some) original

:values of LIST, but rather an array consisting of $_ values after
:evaluating EXPR.
:
:So the following gives you an array of squares:
:
: print grep ($_=$_**2, 1..10)
:
:I find this a nice feature but it is not according to the documentation.
:Or is it a BUG?

I find this very useful (now that I know about it). If it is a bug I'd rather
see it as a bug in the documentation. Please keep this feature!

Jan D.

0 new messages