• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 270
  • Last Modified:

Perl logic question for file

Experts, I have a logic question first, just to make sure that I have the most efficient
plan and then hope to get some actual code to understand any suggestions
with the logic...

I have software that saves its info as a txt file.  I need to parse this file and capture
certain lines, which also tell me more about the number of entries or lines in it.
I notice that there are sets of info, mostly numbers, separated by txt.
The first 50 or so lines remain the same, so
I decided to populate them in an array

if (@lines[6]) {$ownern=@lines[6];} else { $ownern= "owner name empty";}{

Open in new window



Below the 50 line there may be txt like,

Cars
2

Honda
4
1
20

Ford
4
5
15

So, the first 2 lines here tell us that
1 we are in the car section,
2 there are 2 listed
after each make, there is 4 for doors, a color code and asking price...

To continue with the file, there could be any number of Trucks, Vans may be even boats.
Those headings may have 29 lines between them as descriptive info, others may have 8 with a widely varying range
(Some files are 1000 lines, others could be 3,000 lines)

I first need to identify headings (Car, Truck etc.), then capture the line number they reside on, and parse the next line or two for the number of records for each, Once that is complete run loops within the data.

Later, for each file we might want to see how many autos have 4 doors, how many are blue, how many cars are under 10k
sounds like a database, but is only on a per file basis.

So, how would you approach ?





0
ghboom
Asked:
ghboom
  • 6
  • 4
1 Solution
 
wilcoxonCommented:
A few questions...

Why do you need to capture the line number it resides on?

How do you want to capture that line 2 in a car entry is # of doors?  Unless there is a key file somewhere, it will require quite a bit of manual setup on your part (or the program).
0
 
ozoCommented:

> if (@lines[6]) {$ownern=@lines[6];} else { $ownern= "owner name empty";}

perl -Mdiagnostics -we ' if (@lines[6]) {$ownern=@lines[6];} else { $ownern= "owner name empty";}'
Scalar value @lines[6] better written as $lines[6] at -e line 1 (#1)
    (W syntax) You've used an array slice (indicated by @) to select a
    single element of an array.  Generally it's better to ask for a scalar
    value (indicated by $).  The difference is that $foo[&bar] always
    behaves like a scalar, both when assigning to it and when evaluating its
    argument, while @foo[&bar] behaves like a list when you assign to it,
    and provides a list context to its subscript, which can do weird things
    if you're expecting only one subscript.
   
    On the other hand, if you were actually hoping to treat the array
    element as a list, you need to look into how references work, because
    Perl will not magically convert between scalars and lists for you.  See
    perlref.


Perhaps you meant to say
$ownern=  $lines[6]||"owner name empty";
0
 
ozoCommented:
Below the 50 line there may be txt like,

Cars
2

Honda
4
1
20

Ford
4
5
15

So, the first 2 lines here tell us that
1 we are in the car section,
2 there are 2 listed
after each make, there is 4 for doors, a color code and asking price...

Are there really blank lines between each section?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ozoCommented:
$/="";
while( <DATA> ){
    my ($heading,$count) = split/$/m;
    for( 1..$count ){
        my($make,$doors,$color,$price)=split/\s*^/m,<DATA>;
        $info{$heading}{$make}=[$doors,$color,$price];
    }
}
use Data::Dumper;
print Dumper \%info;
__DATA__
Cars
2

Honda
4
1
20

Ford
4
5
15
0
 
ghboomAuthor Commented:
wilcoxon
   Need the line number, because the very next line tells me how many more entries there will be before the next subject change...

Ozo, Long time ! Yes, there are blank lines...  Cant use a list, unless it can dynamically change. Guess a hash might do it,
but to be honest creating a hash that can dynamically re size in width,  and tallying up how many $Cars{4door}{blue} there are is a pita.

Due to the nature of the project, I cant post the actual file. Wish there was an IM feature.....


0
 
ozoCommented:
What do you want to dynamically change?
0
 
ghboomAuthor Commented:
ozo,

Your last post... I like that... Didnt recognize it at first.

Two further questions, how would i substitute an array instead of DATA ?

and is there any way to choose part of an array that this should act on ...

Say my Array has 1000 lines in it, and I know cars start at line 58, how could
I use what you suggest so it would start on line 58

0
 
ozoCommented:
How are you creating the array?
0
 
ghboomAuthor Commented:
#!/usr/local/bin/perl
use warnings;
$file = 'C:\\Users\\Public\\Documents\\A-perl\\TEST3-.txt';
open(INFO, $file);
@lines = <INFO>;
close(INFO);

$index=0;
foreach $row(@lines) {
	if ($row=~ /^\n/){
		$row="null";
	}
$index++;
push(@newlines,$row);
}

Open in new window

0
 
ghboomAuthor Commented:
Was not the solution I needed, but was able to incorporate it..
0
 
ozoCommented:
#!/usr/local/bin/perl
use warnings;
$file = 'C:\Users\Public\Documents\A-perl\TEST3-.txt';
open(INFO, $file);
$/="";
while( <INFO> ){
    my ($heading,$count) = split/$/m;
    for( 1..$count ){
        my($make,$doors,$color,$price)=split/\n/,<INFO>;
        $info{$heading}{$make}=[map{$_||"null"}$doors,$color,$price];
}


use Data::Dumper;
print Dumper \%info;
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now