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

Read Conditions and Print Message of files

I have to read in multiple files each file starts with a comment or mulitple conditions, currently I am reading in the files in the foler as follows:

@files_found = </public/OpSys/motd/*>;

then I loop through each file and there condition:

foreach $message (@files_found)
{
      open(FILE, $message) or die "Couldn't open file!";
      
then i do the following to extract the conditions:

while(($line = <FILE>) =~ /\s*(repeat:|from:|to:|user:|group:|room:)\s*(.*)\s*/i  && $print == "true")
      {
            $condition = $2;
            
            if(
            if($1 =~ /repeat:/i)
            {
                  $repeat = $condition;
                  
                  print $repeat, "\n";
            }
            elsif($1 =~ /from:/i)
            {
                  print $condition, "\n";
                  
                  #Converts date format into dd-mm-yyyy.
                  $condition =~ /(.*)-(.*)-(.*)/i;
                  
                  #yy to yyyy.
                  $year = $3 + 2000;
                  
                  #MMM char to mm int, using hash map.
                  $month = $mon{$2};
                  
                  $from = $1 . "-" . $month . "-" . $year;

                  #Test print out for from date.
                  print "From:", $from, "\n";
                  
                  if(compareDate($from) => 0)
                  {
                        $print = "false";
                        
                        print $print, "\n";
                  }
                  else
                  {
                        $print = "true";
                        
                        print $print, "\n";
                  }
            }
            elsif($1 =~ /to:/i)
            {
                  $to = $condition;
            }
            elsif($1 =~ /user:/i)
            {
                  $user = $condition;
            }
            elsif($1 =~ /group:/i)
            {
                  $group = $condition;
            }
            elsif($1 =~ /room:/i)
            {
                  $room = $condition;
            }
      }

I find the use of all the if conditions realy stupid is there a better way to do this....
and then I want it to go to the next file if any of the conditions have been found to be false. else it should print the message.

any ideas?
0
semIT
Asked:
semIT
  • 3
  • 2
1 Solution
 
kanduraCommented:
Do you actually use all those $to, $user, $group etc?
You may get more efficient and readable code by assigning to a hash:

while(($line = <FILE>) =~ /\s*(repeat:|from:|to:|user:|group:|room:)\s*(.*)\s*/i  && $print == "true")
    {
        my %what;
        $what{$1} = $2;
        if($what{'from:'}) {
            # do the date conversion
        }
    }

I would probably also move the colon out of the first capturing group.
0
 
semITAuthor Commented:
I have to use all of thesse options.... currently I haven't implemented them yet, however it is possible that all the conditions are set. Further more it could be that there is a duplicate of the conditon such as

from: 23-Jan-05
from: 22-Jan-05

in that case the last one should be used.

I don't quiet understand how this hash thing would work for this purpous
0
 
kanduraCommented:
A hash is also called a dictionary in other languages. It's basically a lookup table, where the keys are unique.
That means that there can be at most one key with 'from:' in a hash at all times.
If you do it like this:

    my %what;
    while(($line = <FILE>) =~ /\s*(repeat:|from:|to:|user:|group:|room:)\s*(.*)\s*/i  && $print == "true")
    {
        $what{$1} = $2;
        if($what{'from:'}) {
            # do the date conversion
        }
    }

then you'll find that the values stored in %what are always the latest ones found.
suppose you would have these two lines in the file:

from: 23-Jan-05
from: 22-Jan-05

Then the first iteration assigns
    $what{'from:'} = '23-Jan-05';
and the second iteration assigns
    $what{'from:'} = '22-Jan-05';

This is equivalent to what you're doing now: $from always holds the last date it encountered, as does the hash.
The hash will also contain all the other entries you're filtering on, for instance
    $hash{'repeat:'}
will contain the last 'repeat' entry found.

Let's go through another example with the following data in your file:

repeat: 1
from: 23-Jan-05
group: S5
repeat: 2
from: 22-Jan-05

Let's see what the while loop does to the hash:
line 1:
    $what{'repeat:'} = 1;
line 2:
    $what{'from:'} = '23-Jan-05';
    (note that $what{'repeat:'} is untouched, and still contains 1)
line 3:
    $what{'group:'} = 'S5';
line 4:
    $what{'repeat:'} = 2;
    (note that the old value of 1 is overwritten)
line 5:
    $what{'from:'} = '22-Jan-05';

At this point, %what contains the following:

%what = (
    'repeat:'   => 2,
    'group:'    => 'S5',
    'from:'     => '22-Jan-05',
);

In your original script, you would have
$group  = 'S5';
$from   = '22-Jan-05';
$repeat = 2;

So the hash does away with all your "if" statements, and the code becomes cleaner.
0
 
semITAuthor Commented:
thats great --- just one more thing... how can I then loop through all the conditions in the hash table to check them?
0
 
kanduraCommented:
There are several ways: you could use "keys" to get all keys in the hash, or use "each" to iterate over all pairs:

    foreach my $key(keys %what) {
        print "$key = $what{$key}\n";
    }

or

    while (my ($key, $val) = each %what) {
        print "$key = $val\n";
    }

0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now