Ik heb een text file met verschillende records, ik wil op deze een
rekenbewerking loslaten.
De vier getalen na het "=" teken wil ik vermenigvuldigen met vier, het
laatste getal niet.
19970522000000=1.68,1.68,1.63,1.66,50384
19970523000000=1.66,1.68,1.63,1.68,51213
19970526000000=1.68,1.68,1.61,1.68,28505
19970527000000=1.68,1.68,1.63,1.68,52228
19970528000000=1.66,1.68,1.63,1.68,118430
19970529000000=1.66,1.68,1.61,1.68,260400
19970530000000=1.66,1.66,1.59,1.63,151400
19970602000000=1.63,1.68,1.59,1.68,408740
Iemand een idee hoe ik dat voorelkaar kan krijgen?
GG
Kees
--
Q: Why did Captain Kirk piss on the bridge?
A: He wanted to boldly go where no man had gone before!
Visit me @ http://www.xs4all.nl/~kostercd/ | ICQ #179658498 -- # EOE
> Hallo,
>
> Ik heb een text file met verschillende records, ik wil op deze een
> rekenbewerking loslaten.
>
> De vier getalen na het "=" teken wil ik vermenigvuldigen met vier, het
> laatste getal niet.
>
> 19970522000000=1.68,1.68,1.63,1.66,50384
> 19970523000000=1.66,1.68,1.63,1.68,51213
> 19970526000000=1.68,1.68,1.61,1.68,28505
> 19970527000000=1.68,1.68,1.63,1.68,52228
> 19970528000000=1.66,1.68,1.63,1.68,118430
> 19970529000000=1.66,1.68,1.61,1.68,260400
> 19970530000000=1.66,1.66,1.59,1.63,151400
> 19970602000000=1.63,1.68,1.59,1.68,408740
>
> Iemand een idee hoe ik dat voorelkaar kan krijgen?
gawk 'BEGIN {FS=",|=";} { printf "%14d=%0.02f,%0.02f,%0.02f,%0.02f,%d\n",$1
$2*4, $3*4, $4*4, $5*4,$6}' input > output
Eric
Hartelijk dank Eric,
Hij werkt nog niet geheel zoals het moet maar hiermee kom ik er wel.
GG
Kees
--
I am myself plus my circumstance, and if I do not save it, I cannot
save myself.
-- Jos' e Ortega Y Gasset
> Hallo,
>
> Ik heb een text file met verschillende records, ik wil op deze
> een rekenbewerking loslaten.
>
> De vier getalen na het "=" teken wil ik vermenigvuldigen met
> vier, het laatste getal niet.
>
> 19970522000000=1.68,1.68,1.63,1.66,50384
> 19970523000000=1.66,1.68,1.63,1.68,51213
> 19970526000000=1.68,1.68,1.61,1.68,28505
> 19970527000000=1.68,1.68,1.63,1.68,52228
> 19970528000000=1.66,1.68,1.63,1.68,118430
> 19970529000000=1.66,1.68,1.61,1.68,260400
> 19970530000000=1.66,1.66,1.59,1.63,151400
> 19970602000000=1.63,1.68,1.59,1.68,408740
>
> Iemand een idee hoe ik dat voorelkaar kan krijgen?
>
> GG
> Kees
Met een Perl scriptje bijv.:
use strict;
use warnings;
my $line;
my ($be, $ae); # before equal sign, after equal sign
my @numbers;
while ($line = <DATA>) {
($be, $ae) = split /=/, $line;
@numbers = split /,/, $ae;
pop @numbers;
@numbers = map {$_ * 4} @numbers;
print join " ", map {"[$_]"} @numbers;
print "\n";
}
__DATA__
19970522000000=1.68,1.68,1.63,1.66,50384
19970523000000=1.66,1.68,1.63,1.68,51213
19970526000000=1.68,1.68,1.61,1.68,28505
19970527000000=1.68,1.68,1.63,1.68,52228
19970528000000=1.66,1.68,1.63,1.68,118430
19970529000000=1.66,1.68,1.61,1.68,260400
19970530000000=1.66,1.66,1.59,1.63,151400
19970602000000=1.63,1.68,1.59,1.68,408740
[6.72] [6.72] [6.52] [6.64]
[6.64] [6.72] [6.52] [6.72]
[6.72] [6.72] [6.44] [6.72]
[6.72] [6.72] [6.52] [6.72]
[6.64] [6.72] [6.52] [6.72]
[6.64] [6.72] [6.44] [6.72]
[6.64] [6.64] [6.36] [6.52]
[6.52] [6.72] [6.36] [6.72]
--
KP
Ik krijg overigens uitsluitend virussen van mensen met een
virusscanner. Mensen zonder virusscanner sturen mij nooit
virussen. Gek he? --- V. Sessink in nl.comp.os.linux.overig
> my $line;
> my ($be, $ae); # before equal sign, after equal sign
declareer vars waar je ze gebruikt. Daarnaast, $before_equal,
$after_equal had je dat commentaar kunnen besparen :-D.
> my @numbers;
> while ($line = <DATA>) {
while ( my $line = <DATA> )
> ($be, $ae) = split /=/, $line;
dus hier: my ( $be, $ae )
Andere oplossing:
my ( @numbers ) = $line =~ /(\d+\.\d+)/g;
> @numbers = map {$_ * 4} @numbers;
> print join " ", map {"[$_]"} @numbers;
> print "\n";
print "[",
join ( "] [", map { $_ * 4 } @numbers ),
"]\n";
Als de getallen in een bestand staan, kan:
#!perl -n
use strict;
use warnings;
my ( @numbers ) = $_ =~ /(\d+\.\d+)/g;
print "[",
join ( "] [", map { $_ * 4 } @numbers ),
"]\n";
handig zijn (zie perl -h voor de -n optie)
Of wellicht:
#!perl -n
use strict;
use warnings;
my ( $stamp, @numbers ) = split /[=,]/;
my $count = pop @numbers;
print "$stamp=",
join ( ",", map { $_ * 4 } @numbers ),
",$count";
( merk op dat $count de \n nog bevat )
En een meer awky oplossing:
#!perl -naF[=,]
printf "%14s=%0.02f,%0.02f,%0.02f,%0.02f,%d\n",
$F[ 0 ], ( map { $_ * 4 } @F[ 1..4 ] ), $F[ 5 ];
De "one liner" is left as an excercise ;-)
( merk op: %14s ipv %14d, getal was hier te groot (WinXP) )
--
John Bokma
Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
>> ($be, $ae) = split /=/, $line;
>
> dus hier: my ( $be, $ae )
Nee, want dan haal je de my binnen de loop. En bij een loop van
een miljoen, wil je die er echt buiten hebben :-p
> print "[",
>
> join ( "] [", map { $_ * 4 } @numbers ),
>
> "]\n";
Die gebruikte ik vroeger ook altijd. Ben deze
>> print join " ", map {"[$_]"} @numbers;
een keer in clpm tegen gekomen en vindtum wel zo fraai.
> #!perl -naF[=,]
> printf "%14s=%0.02f,%0.02f,%0.02f,%0.02f,%d\n",
> $F[ 0 ], ( map { $_ * 4 } @F[ 1..4 ] ), $F[ 5 ];
AAAAARRRRGHHHH!!!!
'dorie John, hou daar nu eens me op!
>>> ($be, $ae) = split /=/, $line;
>> dus hier: my ( $be, $ae )
> Nee, want dan haal je de my binnen de loop. En bij een loop van
> een miljoen, wil je die er echt buiten hebben :-p
Zou je denken? In sommige talen klopt je denkrichting wel,
maar in andere (gecompileerde) talen wordt op die manier
de variabele nog steeds maar eenmalig opgezet, en daarmee
beperk je zo mooi de scope van die variabele, want hij is
echt 'weg' (onbereikbaar) na de loop.
De vraag is dus: hoe doet perl het.
En perl doet het precies zoals John impliceerde:
A declaration can be put anywhere a statement can, but has no effect
on the execution of the primary sequence of statements -- declarations
all take effect at compile time.
Typically all the declarations are put at the beginning or the end of
the script. However, if you're using lexically-scoped private variables
created with my(), you'll have to make sure your format or subroutine
definition is within the same block scope as the my if you expect to
be able to access those private variables.
Ofwel: alle declaraties worden door de compiler gedaan alsof ze
voorin staan. De scope van de door 'my()' gemaakte variabelen
is beperkt tot de block-scope van het block waarin ze staan.
--
Affijn, Ruud ` - ´
+ ` ´ *
´ ` Jvr qvg yrrfg,
´ = ` fgresg wbatre.
$ perl bench 100
Benchmark: timing 100 iterations of in loop, out loop...
in loop: 11 wallclock secs (10.03 usr + 0.00 sys = 10.03 CPU) @ 9.97/s (n=100)
out loop: 6 wallclock secs ( 5.54 usr + 0.00 sys = 5.54 CPU) @ 18.05/s (n=100)
De code:
'in loop' => sub { for (my $i = 0; $i < $num; $i++) { my ($a, $b); } }
'out loop' => sub { my ($a, $b); for (my $i = 0; $i < $num; $i++) { } }
($num = 100000, v5.8.1-RC3)
> Ofwel: alle declaraties worden door de compiler gedaan alsof ze voorin
> staan. De scope van de door 'my()' gemaakte variabelen is beperkt tot de
> block-scope van het block waarin ze staan.
En kennelijk kost de check of een variabele in scope is of niet toch wel
enige rekenkracht.
--
robert
> Ofwel: alle declaraties worden door de compiler gedaan alsof ze
> voorin staan. De scope van de door 'my()' gemaakte variabelen
> is beperkt tot de block-scope van het block waarin ze staan.
Klopt. Maar zoals robert terecht al liet ziet, het punt is niet de
feitelijke declaratie, maar het bepalen van de scope.
Koos
--
43rd Law of Computing: Anything that can go wr
fortune: Segmentation violation -- Core dumped
> John Bokma wrote (Tuesday 22 February 2005 18:58):
>
>>> ($be, $ae) = split /=/, $line;
>>
>> dus hier: my ( $be, $ae )
>
> Nee, want dan haal je de my binnen de loop. En bij een loop van
> een miljoen, wil je die er echt buiten hebben :-p
Omdat?
>> print "[",
>>
>> join ( "] [", map { $_ * 4 } @numbers ),
>>
>> "]\n";
>
> Die gebruikte ik vroeger ook altijd. Ben deze
>
>>> print join " ", map {"[$_]"} @numbers;
>
> een keer in clpm tegen gekomen en vindtum wel zo fraai.
Oh, maar er zit weinig verschil in, alleen doe ik stiekem die maal 4 ook
in die map.
>> #!perl -naF[=,]
>> printf "%14s=%0.02f,%0.02f,%0.02f,%0.02f,%d\n",
>> $F[ 0 ], ( map { $_ * 4 } @F[ 1..4 ] ), $F[ 5 ];
>
> AAAAARRRRGHHHH!!!!
> 'dorie John, hou daar nu eens me op!
Die 14 kan vast weg voor die %, maakt het weer leesbaarder, toch?
Benchmark: timing 100 iterations of in, out...
in: 104 wallclock secs (86.56 usr + 0.02 sys = 86.58 CPU) @
1.16/s (n=100)
out: 85 wallclock secs (76.64 usr + 0.01 sys = 76.66 CPU) @
1.30/s (n=100)
use strict;
use warnings;
use Benchmark qw(:all) ;
timethese( 100, {
'in' => sub {
my ( $a, $b );
for ( my $i = 0; $i < 1000000; $i++ ) {
$a = undef;
$b = undef;
$a += $i;
$b += $i;
}
} ,
'out' => sub {
for ( my $i = 0; $i < 1000000; $i++ ) {
my ( $a, $b );
$a += $i;
$b += $i;
}
} ,
});
This is perl, v5.8.3 built for MSWin32-x86-multi-thread
(with 8 registered patches, see perl -V for more detail)
> En kennelijk kost de check of een variabele in scope is of niet
> toch wel enige rekenkracht.
Aha. Ik heb het net ook maar eens uitgeprobeerd, en het gaat zelfs
nog verder: de my-variabele wordt bij elke passage opnieuw opgezet,
met waarde 0.
use strict;
my $num = 10;
my ($a, $b) = ("*A*", "*A*");
print "A: a=$a, b=$b\n";
sub inloop {
print "\n-inloop--\n";
print "{a=$a, b=$b}\n";
for (my $i = 0; $i < $num; $i++) {
my $a++;
my $b += $a;
print "{{a=$a, b=$b}}\n";
}
print "{a=$a, b=$b} !!!\n";
print "-inloop--\n";
}
my ($a, $b) = ("*B*", "*B*");
print "B: a=$a, b=$b\n";
sub outloop {
print "\n-outloop--\n";
print "{a=$a, b=$b} !!!\n";
my ($a, $b);
for (my $i = 0; $i < $num; $i++) {
$a++;
$b += $a;
print "{{a=$a, b=$b}}\n";
}
print "{a=$a, b=$b}\n";
print "-outloop--\n";
}
my ($a, $b) = ("*C*", "*C*");
print "C: a=$a, b=$b\n";
inloop();
print "a=$a, b=$b\n";
outloop();
print "a=$a, b=$b\n";
Zie ook:
http://perl.plover.com/FAQs/Namespaces.html
--
Affijn, Ruud ` - ?
+ ` ? *
? ` Jvr qvg yrrfg,
? = ` fgresg wbatre.
> Toen ik robert kietelde, kwam er dit uit:
>
>> En kennelijk kost de check of een variabele in scope is of niet
>> toch wel enige rekenkracht.
>
> Aha. Ik heb het net ook maar eens uitgeprobeerd, en het gaat zelfs
> nog verder: de my-variabele wordt bij elke passage opnieuw opgezet,
> met waarde 0.
undef zal je bedoelen, en ja, dat klopt :-D, sterker daar is niks mis mee.
En buiten het block waarin je ze definieert kan je ze niet meer gebruiken.
>>> En kennelijk kost de check of een variabele in scope is of niet
>>> toch wel enige rekenkracht.
>> Aha. Ik heb het net ook maar eens uitgeprobeerd, en het gaat zelfs
>> nog verder: de my-variabele wordt bij elke passage opnieuw opgezet,
>> met waarde 0.
> undef zal je bedoelen, en ja, dat klopt :-D, sterker daar is niks
> mis mee.
Je hebt in Perl dus een extra laag {} nodig om het 'netjes' te krijgen:
(netjes als in: de variabelen zijn na het block waarin ze gebruikt
worden, per direct niet meer beschikbaar)
{ my ($a, $b) = (0, 0);
while (busy()) {
$a++;
$b += $a;
print "$b ";
} }
Een my in de for() veroorzaakt blijkbaar iets verborgens, dus dit:
for (my $i = 0; $i < 10; $i++) { ...; }
is eigenlijk dit:
{ my $i;
for ($i = 0; $i < 10; $i++) {
...;
} }
Zie ook "Other Properties of my Variables" op die
URL:http://perl.plover.com/FAQs/Namespaces.html.
> Toen ik John Bokma kietelde, kwam er dit uit:
>> Dr.Ruud:
>>> robert:
>
>>>> En kennelijk kost de check of een variabele in scope is of niet
>>>> toch wel enige rekenkracht.
>
>>> Aha. Ik heb het net ook maar eens uitgeprobeerd, en het gaat zelfs
>>> nog verder: de my-variabele wordt bij elke passage opnieuw opgezet,
>>> met waarde 0.
>
>> undef zal je bedoelen, en ja, dat klopt :-D, sterker daar is niks
>> mis mee.
>
> Je hebt in Perl dus een extra laag {} nodig om het 'netjes' te
> krijgen: (netjes als in: de variabelen zijn na het block waarin ze
> gebruikt worden, per direct niet meer beschikbaar)
Dat kan, en soms zie ik dat inderdaad wel eens, a la
{
local ...
...
}
> Een my in de for() veroorzaakt blijkbaar iets verborgens, dus dit:
>
> for (my $i = 0; $i < 10; $i++) { ...; }
>
> is eigenlijk dit:
>
> { my $i;
> for ($i = 0; $i < 10; $i++) {
> ...;
> } }
Yup, en heel handig dus. Aan de andere kant, in 99 van de 100 Perl
scripts zal je geen for zien op die manier :-D.
[...]
>
> Met een Perl scriptje bijv.:
>
> use strict;
> use warnings;
>
> my $line;
> my ($be, $ae); # before equal sign, after equal sign
> my @numbers;
> while ($line = <DATA>) {
> ($be, $ae) = split /=/, $line;
> @numbers = split /,/, $ae;
> pop @numbers;
> @numbers = map {$_ * 4} @numbers;
> print join " ", map {"[$_]"} @numbers;
> print "\n";
> }
>
[...]
Bedankt Koos, (en alle andere natuurlijk) ik heb je voorbeeld gebruikt
om het volgende Perl progje in elkaar te frutselen.
#v+
#!/usr/bin/perl
if ($#ARGV != 2) {
print "usage: input-file output-file factor\n";
exit;
}
$inputfile = $ARGV[0];
$outputfile = $ARGV[1];
$factor = $ARGV[2];
open(IF, $inputfile);
open(OF, ">$outputfile");
my $line;
my ($bl, $el);
my @numbers;
my $volume;
while ($line = <IF>) {
($bl, $el) = split /=/, $line;
if ($bl > 19000000000000) {
@numbers = split /,/, $el;
$volume = pop @numbers;
@numbers = map {$_ * $factor} @numbers;
use integer;
$volume = $volume / $factor;
print OF $bl;
print OF "=";
print OF join "", map {"$_,"} @numbers;
print OF $volume;
print OF "\n";
} else {
print OF $line;
}
}
close(IF);
close(OF);
exit;
#v-
<INPUT>
ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=8.15,8.36,8.13,8.33,2893070
19940104000000=8.35,8.35,8.26,8.26,4084400
19940105000000=8.33,8.33,8.28,8.3,5622470
20050218000000=21.16,21.28,21.08,21.16,6017510
20050221000000=21.17,21.19,20.82,20.88,6842220
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock
</INPUT>
<OUTPUT> (factor = 4)
ChartPath=/home/sircrow/Qtstalker/data/Stocks/AAB
0=Plugin=HorizontalLine|Name=0|Value=19.9431|Plot=Main Plot|Color=#0055ff
19940103000000=32.6,33.44,32.52,33.32,723267
19940104000000=33.4,33.4,33.04,33.04,1021100
19940105000000=33.32,33.32,33.12,33.2,1405617
20050218000000=84.64,85.12,84.32,84.64,1504377
20050221000000=84.68,84.76,83.28,83.52,1710555
BarType=0
CHARTOBJECTS=0
Plugin=Stocks
Symbol=AAB
Title=AAB
Type=Stock
</OUTPUT>
Er zullen wel wat niet zulk mooie constructies inzitten maar tis m'n
eerste Perl progje, ga vanmiddag naar de bieb een Perl boek zoeken.
GG
Kees
--
momentum, n.:
What you give a person when they are going away.
11:12:05 up 2 days, 1:47, 4 users, load average: 0.27, 0.07, 0.05
> ik heb je voorbeeld gebruikt om het volgende Perl progje in
> elkaar te frutselen.
Voor een eerste frutsel ziet het er prima uit, hoor.
> open(IF, $inputfile);
> open(OF, ">$outputfile");
open(IF, $inputfile) || die "Can't open $inputfile ($!)";
open(OF, ">$outputfile") || die "Can't open $outputfile ($!)";
Ter controle of het wel gelukt is.
> my $line;
> my ($bl, $el);
> my @numbers;
> my $volume;
>
> while ($line = <IF>) {
> ($bl, $el) = split /=/, $line;
> if ($bl > 19000000000000) {
Kan wel. Maar
if (( $bl =~ m|^\d{14}$| ) && ( $bl > 19000000000000)) {
is mooier. Dan weet je zeker dat je met een datum-getal van doen
hebt.
> @numbers = split /,/, $el;
> $volume = pop @numbers;
> @numbers = map {$_ * $factor} @numbers;
> use integer;
Kan wel. Maar mooier is een extra isolatie block. Voor de
programmeur is eea daarmee netter afgewerkt. (In dit specifieke
geval maakt het voor Perl niets uit.)
{
use integer;
...
}
> $volume = $volume / $factor;
> print OF $bl;
> print OF "=";
> print OF join "", map {"$_,"} @numbers;
> print OF $volume;
> print OF "\n";
Of in een regel natuurlijk:
print OF "$bl=".join ("", map {"$_,"} @numbers).($volume/4)."\n";
> Er zullen wel wat niet zulk mooie constructies inzitten maar tis
> m'n eerste Perl progje, ga vanmiddag naar de bieb een Perl boek
> zoeken.
"Learning Perl". Of als je't aandurft: "Programming Perl".
Succes.
>> Een my in de for() veroorzaakt blijkbaar iets verborgens, dus dit:
>>
>> for (my $i = 0; $i < 10; $i++) { ...; }
>>
>> is eigenlijk dit:
>>
>> { my $i;
>> for ($i = 0; $i < 10; $i++) {
>> ...;
>> } }
> Yup, en heel handig dus.
Ja, maar wel verhullend, want de scope van de $var die in de for()
(of in de foreach) staat, heeft dan niet de scope van de
zichtbare {} waar hij tussen staat:
use strict;
sub demo
{
foreach my $text ("A", "B", "C") {
print "text=$text\n";
}
print "text=$text\n"; # compilation-error
}
demo();
> Aan de andere kant, in 99 van de 100 Perl
> scripts zal je geen for zien op die manier :-D.
Als perl het al voor je doet, hoef je het niet zelf meer
te doen. Maar een rammelende syntax blijft het. Kan er even
iemand dit (op theoretische wijze) met C++ vergelijken?
Zoiets als:
for (int i; i < 10; i++) {
int a++;
int b += a;
cout << "a=", a, ", b=", b, '\n';
}
(ongetest)
> Toen ik John Bokma kietelde, kwam er dit uit:
[ snip for ( my ... ]
> Ja, maar wel verhullend, want de scope van de $var die in de for()
> (of in de foreach) staat, heeft dan niet de scope van de
> zichtbare {} waar hij tussen staat:
Dat is idem in Java, idem in C/C++, en wellicht nog in een aantal andere
talen precies hetzelfde :-D.
>> Aan de andere kant, in 99 van de 100 Perl
>> scripts zal je geen for zien op die manier :-D.
>
> Als perl het al voor je doet, hoef je het niet zelf meer
> te doen.
Ik bedoel dus een for met een index, meestal gebruik je dingen als:
for my $item ( @array ) { .. }
> Maar een rammelende syntax blijft het.
Je bedoelt het beperken van de scope of het resetten van de vars binnen de
lus?
Ik heb m'n vingers wel eens gebrand aan vergelijkbare code in Javascript:
for (var i = 0; i < 10; i++) { ... }
Daarmee declareer je een variabele 'i' die binnen het blok dat de for-lus
omvat geldig is, i.t.t. Perl, Java en C/C++ waar 'i' alleen in op het
for-statement-volgende blok geldig is.
--
robert
> Ik heb m'n vingers wel eens gebrand aan vergelijkbare code in
> Javascript:
> for (var i = 0; i < 10; i++) { ... }
>
> Daarmee declareer je een variabele 'i' die binnen het blok dat de
> for-lus omvat geldig is, i.t.t. Perl, Java en C/C++ waar 'i' alleen in
> op het for-statement-volgende blok geldig is.
Auw, en schande! Ik doe mijn best om dat te onthouden, want daar zou ik ook
instinken :-(
> #v+
> #!/usr/bin/perl
Erg belangrijk om hier direct neer te zetten:
use strict;
use warnings;
> if ($#ARGV != 2) {
> print "usage: input-file output-file factor\n";
> exit;
> }
leesbaarder:
unless ( @ARGV == 3 ) {
print ...
exit;
}
> $inputfile = $ARGV[0];
> $outputfile = $ARGV[1];
> $factor = $ARGV[2];
my ( $inputfile, $outputfile, $factor ) = @ARGV;
> open(IF, $inputfile);
or die "Can't open '$inputfile' for reading: $!";
> open(OF, ">$outputfile");
idem.
Met een recente versie van Perl kan je ook:
open my $if, $inputfile or die...
open my $of, '>', $outputfile or die ...
doen
> my $line;
stop in de while
> my ($bl, $el);
stop in de while
> my @numbers;
> my $volume;
ditto
>
> while ($line = <IF>) {
> ($bl, $el) = split /=/, $line;
> if ($bl > 19000000000000) {
> @numbers = split /,/, $el;
> $volume = pop @numbers;
while ( my $line = <$if> ) {
my ( $bl, $el ) = split /=/, $line;
unless ( $bl > 19000000000000 )
print $of $line;
next;
}
Dit is leesbaarder (vind ik), indien er niks te doen is, next.
@numbers = split /,/, $el;
$volume = pop @numbers;
Let op: $volume kan een \n bevatten, maar door
de vermenigvuldiging verderop raak je die kwijt.
> @numbers = map {$_ * $factor} @numbers;
doe ik later :-D.
> use integer;
ai, dat is vrij ticky, sterker, ik zou het ergens weer uitzetten.
> $volume = $volume / $factor;
$volume = int( $volume / $factor );
> print OF $bl;
> print OF "=";
> print OF join "", map {"$_,"} @numbers;
> print OF $volume;
> print OF "\n";
print "$bl=",
join ( ",", map { $_ * $factor } @numbers ),
",volume\n";
> } else {
> print OF $line;
> }
> }
>
> close(IF);
close $if or die "Can't close ... $!"; # [1]
> Er zullen wel wat niet zulk mooie constructies inzitten maar tis m'n
> eerste Perl progje, ga vanmiddag naar de bieb een Perl boek zoeken.
Probeer Learning Perl (O'Reilly) en Perl Cookbook (O'Reilly) te pakken
te krijgen.
[1] recent gehad dat dit echt faalde, de buffer werd door de close weg
geschreven, en .... er was geen ruimte meer op de HD :-D. Als je het
helemaal mooi wilt doen: ( print ...... ) or die ...
[2] En de Koos speciaal voor vandaag:
#!perl -spaF[=,]
next unless $F[0] > 19000000000000;
$_ = "$F[ 0 ]=" . join ',', (
map { $_ * $factor } @F[ 1..4 ]
), int( $F[ 5 ] / $factor ) . "\n"
convert.pl -factor=4 in.txt > out.txt
>> Maar een rammelende syntax blijft het.
> Je bedoelt het beperken van de scope of het resetten
> van de vars binnen de lus?
De 'implied braces'. (0 hits op google)
[...]
>
> "Learning Perl". Of als je't aandurft: "Programming Perl".
>
> Succes.
>
De bovenstaande hadden ze niet, tis "Perl in 24 uur" geworden van
Clinton Pierce.
John en Koos bedankt voor de tips en correcties.
GG
Kees
--
Better hope you get what you want before you stop wanting it.
21:15:55 up 2 days, 11:50, 4 users, load average: 0.06, 0.18, 0.31
> Toen ik John Bokma kietelde, kwam er dit uit:
>> Dr.Ruud:
>
>>> Maar een rammelende syntax blijft het.
>
>> Je bedoelt het beperken van de scope of het resetten
>> van de vars binnen de lus?
>
> De 'implied braces'. (0 hits op google)
Er zijn meer talen die dat doen (Java, C, C++), dus ik zie het probleem
niet. Kwalijker (vind ik) is wat robert als voorbeeld gaf, dat de
variable ineens leeft buiten de lus, dus:
my $a;
for $a ( ... ) {}
en
for my $a ( ... ) {}
zijn dan equivalent.
Dan heb ik liever
{ my $a; for $a ( ... ) {}}
>> Nee, want dan haal je de my binnen de loop. En bij een loop van
>> een miljoen, wil je die er echt buiten hebben :-p
>
> Omdat?
Verkeerde lokvoer meneer Bokma. Ze willen niet bijten vandaag :-)
Dr.Ruud wrote:
> Als perl het al voor je doet, hoef je het niet zelf meer
> te doen. Maar een rammelende syntax blijft het. Kan er even
> iemand dit (op theoretische wijze) met C++ vergelijken?
> Zoiets als:
>
> for (int i; i < 10; i++) {
> int a++;
Bovenstaande regel is geen geldig C++. "int a;" mag wel.
En indien het welk geldig C++ zou zijn: welke beginwaarde
heeft a dan?
> int b += a;
Weer geen geldig C++. "int b = expression;" mag, maar += mag niet.
> cout << "a=", a, ", b=", b, '\n';
> }
Sjoerd
Het is ook zo in C++. Alleen was er in de begindagen van C++,
voor standaardisatie, ooit een andere regel in gebruik binnen
Microsoft en waarschijnlijk compileerde hun enorme codebase niet
met de nieuwe regel, dus in Visual C++ 6.0 was de oude regel nog
steeds de default.
Tegenwoordig doen de Microsoft compilers het wel volgens de C++
standaard.
>>Yup, en heel handig dus.
>
> Ja, maar wel verhullend, want de scope van de $var die in de for()
> (of in de foreach) staat, heeft dan niet de scope van de
> zichtbare {} waar hij tussen staat:
Er is sowieso geen een-op-een verband tussen de scope van
een variabele en de {} haken:
{
int a; // a nr 1
{
float a; // a nr 2
// hier is a nr 1 niet zichtbaar
// hier is b niet zichtbaar
}
int b;
}
De buitenste haken omsluiten zowel "int a;" als "int b;" maar toch
is de scope van zowel die a als de b niet hetzelfde als de {}.
Sjoerd
> [implied braces]
> Er zijn meer talen die dat doen (Java, C, C++), dus ik zie het
> probleem niet.
Het is in zoverre een probleem dat het een uitzondering is op
de {}-structuur. Er zijn C++ compilers die er een compiler-optie
voor hebben, waarmee je dus de {}-structuur leidend maakt, net
als in JavaScript.
Uit de beschrijving van de taal moet goed blijken dat het scope-
blok niet altijd bij de start-accolade begint, maar dat er soms
iets bijzonders aan de hand is. Bij de for() geldt dat overigens
alleen voor het eerste deel, dus voor de eerste ';'
use strict;
sub init { return ($_[0] + 5); }
for (my $a = init(my $b = -1); $a <= 10; $a++) {
$b += $a;
print "a=$a, b=$b\n";
}
print "a=$a, b=$b\n"; # a en b beide unset
> Kwalijker (vind ik) is wat robert als voorbeeld gaf,
> dat de variable ineens leeft buiten de lus
Ik vind dat niet kwalijk. Het moet gewoon goed duidelijk zijn
welke conventie geldt.
Om portable code te maken, moet je dus eigenlijk
{ for (int var=0;;) {...} }
code schrijven, of eigenlijk zelfs
{ int var; for (var=0;;) {...} }
maar dat was ik niet echt van plan. Maar wat nu niet is,
kan best nog komen.
Herbruikbaarheid van mijn C/C++ code in JavaScript heb ik nooit
echt belangrijk gevonden. Mocht ik iets in JavaScript gaan maken,
dan zet ik dat extra {}-schild wel om de for/foreach/while/switch/
do-until/etc.-blokken (dat zijn er overigens te veel, de scope-
variatie is niet bij elk blok-type mogelijk) heen, met een droog
commentaartje erbij.
> Toen ik John Bokma kietelde, kwam er dit uit:
>
>> [implied braces]
>> Er zijn meer talen die dat doen (Java, C, C++), dus ik zie het
>> probleem niet.
>
> Het is in zoverre een probleem dat het een uitzondering is op
> de {}-structuur. Er zijn C++ compilers die er een compiler-optie
> voor hebben, waarmee je dus de {}-structuur leidend maakt, net
> als in JavaScript.
>
> Uit de beschrijving van de taal moet goed blijken dat het scope-
> blok niet altijd bij de start-accolade begint, maar dat er soms
> iets bijzonders aan de hand is.
Voor mij is het met Perl en Java duidelijk :-D.
> Bij de for() geldt dat overigens
> alleen voor het eerste deel, dus voor de eerste ';'
>
> use strict;
> sub init { return ($_[0] + 5); }
> for (my $a = init(my $b = -1); $a <= 10; $a++) {
> $b += $a;
> print "a=$a, b=$b\n";
> }
> print "a=$a, b=$b\n"; # a en b beide unset
Let op: $a en $b zijn bijzondere variabelen:
use strict;
use warnings;
for ( my $x = 0;; my $y = 3) { last }
print $x;
print $y;
vs:
use strict;
use warnings;
for ( my $a = 0;; my $b = 3) { last }
print $a;
print $b;
btw:
use strict;
use warnings;
for ( my $x = 0; $x < 2; my $y = 3) { $y++; $x++; print "$x $y\n"; }
>> Kwalijker (vind ik) is wat robert als voorbeeld gaf,
>> dat de variable ineens leeft buiten de lus
>
> Ik vind dat niet kwalijk. Het moet gewoon goed duidelijk zijn
> welke conventie geldt.
Ok, voor mij ( C, C++, Java, Perl achtergrond ) is het kwalijk :-D.
> { int var; for (var=0;;) {...} }
>
> maar dat was ik niet echt van plan. Maar wat nu niet is,
> kan best nog komen.
Yikes.
> Herbruikbaarheid van mijn C/C++ code in JavaScript heb ik nooit
> echt belangrijk gevonden.
Ik moet er niet aan denken dat ik code in taal a zo op moet zetten dat
het bijna in taal b te gebruiken is. Ik raad altijd aan om in taal a in
a te programmeren, niet b ( dus geen #define begin { en zo :-D)
...
> Het is ook zo in C++. Alleen was er in de begindagen van C++,
> voor standaardisatie, ooit een andere regel in gebruik binnen
> Microsoft en waarschijnlijk compileerde hun enorme codebase niet
> met de nieuwe regel, dus in Visual C++ 6.0 was de oude regel nog
> steeds de default.
Volgens mij was dat gewoon een bug in hun C++ preprocessor.
S.
> Ik heb m'n vingers wel eens gebrand aan vergelijkbare code in Javascript:
> for (var i = 0; i < 10; i++) { ... }
> > Daarmee declareer je een variabele 'i' die binnen het blok dat de for-lus
> omvat geldig is, i.t.t. Perl, Java en C/C++ waar 'i' alleen in op het
> for-statement-volgende blok geldig is.
vc++.6.0 doet het verkeerd. ik heb nogal wat code waarbij ik de i
expliciet buiten de for definieer om cross-platform te blijven. vanaf
vc++.NET is het meen ik opgelost.
groetjes, su.