Beginner: read in lines array1 and after keyword array2

K

kenslaterpa

Marek said:
Have no idea, whether this one is an easy task, or not. I have a file with
tab-delimited Data. These Data have two parts, and I want to read in the
Data in two different arrays from a certain /keyword/ on. I made an
exercise, thinking, wow it's working, but later I realized, that everything
was read into the first array :-( My idea of solving this task seems
probably naive, but I have no clue, how to achieve this otherwise.

Is there somebody, who could give me a hint?


thank you all for your patience


marek

#############


#!/usr/bin/perl

use warnings;
use strict;


my (@lines1, @lines2);

while (<DATA>)
{
push @lines1, $_;
if (/keyword/)
{
push @lines2, $_;
}
}

print "here are the first part of lines:\n";
print join ("\n",@lines1);
print "here are the second part of lines:\n";
print join ("\n",@lines2);

__DATA__

37086,4 15445 808 19,5 3156,3
37667 15769,2 817 19,5 3621
37936,5 15929,6 823 19,5 3857,8
38147,5 16058 827 19,5 4042,8
38371,8 16188,6 833 19,5 4247,4
38607,7 16252,7 837 19,5 4359,2
38752,7 16351,6 844 20,5 4523,9
38774,2 16351,6 844 20,5 4526,9
39056,9 16499,8 849 20,5 4740,6
39249,2 16574,6 853 20,5 4854,6

39720,7 16762,9 864 21,5 5148,7
39932 16847,6 872 22 5289,8
40002,6 16852,9 874 22 5307


keyword


17.07.2006 CC mU 58.00
17.07.2006 Fr. Knorr CC mU 60.00
18.07.2006 Unterföhring MUC Link CC mU 45.00
19.07.2006 CC mU 58.00
20.07.2006 MUC Hanauer Hermann/Wacki CC mU 55.00
21.07.2006 Claudio/Rock CC oU 55.00
24.07.2006 CC mU 54.00
24.07.2006 CC mU 50.00
24.07.2006 CC mU 55.00
25.07.2006 CC mU 82.00
26.07.2006 -3.7 Uhr! Königin MUC Wacki Bar oU
55.00
27.07.2006 hin rück Link CC mU 122.00

Based on looking at the script (I haven't run it), I would think your
@lines2 array
would have one element - the keyword line. As your 'if' statement will
only be
true on that line.
if (/keyword/)
{
push @lines2, $_;
}

All lines are being pushed onto @lines1 without any check.

A quick solution is to set a variable when you hit the keyword line:

$foundKeyword = 1 if /keyword/;

Then push onto the appropriate array based on the value of this
variable
($foundKeyword in the above example).

Ken
 
M

Marek Stepanek

Have no idea, whether this one is an easy task, or not. I have a file with
tab-delimited Data. These Data have two parts, and I want to read in the
Data in two different arrays from a certain /keyword/ on. I made an
exercise, thinking, wow it's working, but later I realized, that everything
was read into the first array :-( My idea of solving this task seems
probably naive, but I have no clue, how to achieve this otherwise.

Is there somebody, who could give me a hint?


thank you all for your patience


marek

#############


#!/usr/bin/perl

use warnings;
use strict;


my (@lines1, @lines2);

while (<DATA>)
{
push @lines1, $_;
if (/keyword/)
{
push @lines2, $_;
}
}

print "here are the first part of lines:\n";
print join ("\n",@lines1);
print "here are the second part of lines:\n";
print join ("\n",@lines2);

__DATA__

37086,4 15445 808 19,5 3156,3
37667 15769,2 817 19,5 3621
37936,5 15929,6 823 19,5 3857,8
38147,5 16058 827 19,5 4042,8
38371,8 16188,6 833 19,5 4247,4
38607,7 16252,7 837 19,5 4359,2
38752,7 16351,6 844 20,5 4523,9
38774,2 16351,6 844 20,5 4526,9
39056,9 16499,8 849 20,5 4740,6
39249,2 16574,6 853 20,5 4854,6

39720,7 16762,9 864 21,5 5148,7
39932 16847,6 872 22 5289,8
40002,6 16852,9 874 22 5307


keyword


17.07.2006 CC mU 58.00
17.07.2006 Fr. Knorr CC mU 60.00
18.07.2006 Unterföhring MUC Link CC mU 45.00
19.07.2006 CC mU 58.00
20.07.2006 MUC Hanauer Hermann/Wacki CC mU 55.00
21.07.2006 Claudio/Rock CC oU 55.00
24.07.2006 CC mU 54.00
24.07.2006 CC mU 50.00
24.07.2006 CC mU 55.00
25.07.2006 CC mU 82.00
26.07.2006 -3.7 Uhr! Königin MUC Wacki Bar oU
55.00
27.07.2006 hin rück Link CC mU 122.00
 
M

Marek Stepanek

On 30 Jul 2006 14:07:06 +0200, Michele Dondi <[email protected]>
wrote:

my (@lines1, @lines2);
while (<DATA>)
{
last if /keyword/;
push @lines1, $_;
}
@lines2=<DATA>;
....

push @{ 1../keyword/ ? \@lines1 : \@lines2 }, $_ while <>;


Michele


Hello Michele,


thank you! This was a great help. The second solution is so tricky, that I
hardly understand, what's going on there. And I take the second one, it
looks so professional :)


greetings from Munich


marek
 
M

Marek Stepanek



Thank you Michele, for taking the time to explain this cryptic line.
push @{ 1../keyword/ ? \@lines1 : \@lines2 }, $_ while <DATA>;
I understood now, how this is working. But I am far of being able, to write
such code alone :-( Great lesson! I have a supplemental question to the
list, which is not on topic under this subject, but perhaps I may dare to do
this as a beginner ...

once again my DATA:

__DATA__

37086,4 15445 808 19,5 3156,3
37667 15769,2 817 19,5 3621
37936,5 15929,6 823 19,5 3857,8
38147,5 16058 827 19,5 4042,8
38371,8 16188,6 833 19,5 4247,4
38607,7 16252,7 837 19,5 4359,2
38752,7 16351,6 844 20,5 4523,9
38774,2 16351,6 844 20,5 4526,9
39056,9 16499,8 849 20,5 4740,6
39249,2 16574,6 853 20,5 4854,6

39720,7 16762,9 864 21,5 5148,7
39932 16847,6 872 22 5289,8
40002,6 16852,9 874 22 5307


keyword


17.07.2006 CC mU 58.00
17.07.2006 Fr. Knorr CC mU 60.00
18.07.2006 Unterföhring MUC Link CC mU 45.00
19.07.2006 CC mU 58.00
20.07.2006 MUC Hanauer Hermann/Wacki CC mU 55.00
21.07.2006 Claudio/Rock CC oU 55.00
24.07.2006 CC mU 54.00
24.07.2006 CC mU 50.00
24.07.2006 CC mU 55.00
25.07.2006 CC mU 82.00
26.07.2006 -3.7 Uhr! Königin MUC Wacki Bar oU
55.00
27.07.2006 hin rück Link CC mU 122.00

for the first part I add with a subroutine the day and dates (with the
module use Date::Calc); each line is a new day, also the empty one. The
first part I read into the @array1 with Michele's genius line :) The second
part I read into the @array2. I want to add into an new array or into the
array1 the number of the lines, where the dates are the same like in arryay2
AND where the element is containing oU ...

so @array1 (or the new array3) becomes like follows and ->this<- is inserted
from @array2:

Mon, 17.07.2006 37667.00 15769.20 817 19.50 3621.00
Die, 18.07.2006 37936.50 15929.60 823 19.50 3857.80
Mit, 19.07.2006 38147.50 16058.00 827 19.50 4042.80
Don, 20.07.2006 38371.80 16188.60 833 19.50 4247.40
Fre, 21.07.2006 38607.70 16252.70 837 19.50 4359.20 ->55.00<-
Sam, 22.07.2006 38752.70 16351.60 844 20.50 4523.90
Son, 23.07.2006 38774.20 16351.60 844 20.50 4526.90
Mon, 24.07.2006 39056.90 16499.80 849 20.50 4740.60
Die, 25.07.2006 39249.20 16574.60 853 20.50 4854.60
Mit, 26.07.2006 39249.20 16574.60 853 20.50 4854.60 ->55.00<-
Don, 27.07.2006 39720.70 16762.90 864 21.50 5148.70
Fre, 28.07.2006 39932.00 16847.60 872 22.00 5289.80
Sam, 29.07.2006 40002.60 16852.90 874 22.00 5307.00


thank you once again

marek
 
B

Ben Morrow

Quoth Michele Dondi said:
Oh, and one funky (IMHO) solution which will put the keyword line into
@lines1 (one can pop() it afterwards):

push @{ 1../keyword/ ? \@lines1 : \@lines2 }, $_ while <>;

Or, clearer once one understands the uses of .. in scalar context:

if (1../keyword/) {
push @lines1, $_;
}
else {
push @lines2, $_;
}

1../keyword/ should be read as 'we are between line 1 and a line which
matches /keyword/', so this reads as

if we are between line 1 and a line which matches /keyword/,
push the current line onto @lines1,
otherwise
push the current line onto @lines2.

Michele's code is basically a way of working around the fact that you
can't say

push( (foo ? @foo : @bar), $_ );

in Perl5 as the ?: operator won't accept arrays.

Ben
 
J

John W. Krahn

Ben said:
Michele's code is basically a way of working around the fact that you
can't say

push( (foo ? @foo : @bar), $_ );

in Perl5 as the ?: operator won't accept arrays.

The ?: operator works just file with scalars/arrays/hashes/lists. That won't
work because push() only works with arrays as the first argument and not
scalars/hashes/lists.



John
 
A

anno4000

Michele Dondi said:
Oh, and one funky (IMHO) solution which will put the keyword line into
@lines1 (one can pop() it afterwards):

push @{ 1../keyword/ ? \@lines1 : \@lines2 }, $_ while <>;

Slightly less funky:

$/ = "keyword\n";
my @lines1 = split /\n/, <DATA>;
my @lines2 = split /\n/, <DATA>;

Anno
 
M

Marek Stepanek

You're very polite and I think most people wouldn't have any problem
with your request. But even though other ones are now partecipating to
this thread, chances are that someone may think this part of the
thread having become some sort of private conversation among us. So if
your other question logically fits better in a separate thread, then
start a new one. In this precise moment I'm at a hospital and I don't
have time to look further into your post. I'll give another peek into
it later, if time and therapies permit!


Michele


And I am only online the evening, so this great thank you is coming late. I
specially appreciated the suggestion of Anno :)

And to you Michele all the best for your health. I will make a new thread,
with my supplemental question this weekend. In any case I have had bad
conscience to add this question again, abusing your help, without trying to
solve this problem myself first.


greetings from Munich, finally a little rain


marek
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,823
Latest member
Nadia88

Latest Threads

Top