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
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')
[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!"=/
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, :-)
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
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" :-),
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.