Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: How to Extract Data from Text file 1 based on the Value from Text file 2

by serf (Chaplain)
on Mar 04, 2010 at 11:58 UTC ( #826691=note: print w/ replies, xml ) Need Help??


in reply to How to Extract Data from Text file 1 based on the Value from Text file 2

Hi roborat, welcome to Perl Monks. While almut was away coding you a solution, I was doing the same... and got a few interruptions so was beaten to it... There are a couple of things that I would correct in your example code, because they will help you in your future work.

#use strict; #use warnings;
use warnings and use strict are your friends, you should use them. You have them commented out here. This isn't C where you have # in the front of declarations, in Perl a # at the start of a line is usally for commenting out that line.
open(CUST_DATA,'<', $cust_file) || die("Could not open file!");
If you're going to die on failure (which you should do) you'll help yourself a lot by giving as much information as possible as to why it's failed. If the failure is due to an incorrect file name, you'll want to know what file name the program was trying to open, to see if it's different from what you were expecting it to be using. It can help to protect the name in single quotes, like: die "Can't read '$filename': $!\n" so you can easily spot leading or trailing spaces in the name which can catch you. Also use the "$!" at the end of the line which tells you the error message associated with the reason the action failed - this is a BIG help. Here is my quick stab at the code... Things to note, I like to use hash references because it can make it easier to deal with the data later. I've trapped to catch lines with unrecognized customer IDs. I've also sorted by customer name. You could turn these off if not applicable, but they may be useful. I hope this helps...
#!/usr/bin/perl # # # use warnings; use strict; my $cust_file = "customer.txt"; my $billing_file = "2010.bill"; my $cust; open (CUST_DATA, $cust_file) || die "Can't read '$cust_file': $!\n"; while (defined (my $line = <CUST_DATA>)) { chomp $line; # Remove trailing newline my ($cust_id,$cust_name) = split(/:/,$line); $cust->{$cust_id}->{name} = $cust_name; } close(CUST_DATA); my @bill_fields = qw(cust_id x_cust_id2 Device_Code Port Traf_Dir x_st +art_date x_end_date x_number Data_Usage); my $bill_line; my $bill_data; open(BILL_DATA, $billing_file) || die "Can't read '$billing_file': $!\ +n"; while (defined (my $line = <BILL_DATA>)) { chomp $line; @{$bill_line}{@bill_fields} = split(/\s/, $line); if ( ! $cust->{ $bill_line->{cust_id} }->{name} ) { die "$0: Found unknown customer ID [$bill_line->{cust_id}] on +line $. of '$billing_file'\n"; } $bill_data->{ $bill_line->{cust_id} }->{ $bill_line->{Device_Code} + }->{ $bill_line->{Port} }->{ $bill_line->{Traf_Dir} } = $bill_line-> +{Data_Usage}; } close(BILL_DATA); sub by_name ($$) { return $cust->{$a}->{name} <=> $cust->{$b}->{name}; } for my $customer ( keys %$cust ) { print "CUSTOMER NAME: $cust->{$customer}->{name}\n" . "Device_Code Port Traf_Dir Data_Usage\n"; for my $device ( sort by_name keys %{$bill_data->{$customer}} ) { for my $port ( sort keys %{$bill_data->{$customer}->{$device}} + ) { (my $short_port = $port) =~ s/^FastEthernet/Fa/g; for my $direction qw(OUT IN) { print "$device $short_port $direction " . $bill_data->{$customer}->{$device}->{$port}->{$dir +ection} . $/; } } } }


Comment on Re: How to Extract Data from Text file 1 based on the Value from Text file 2
Select or Download Code
Re^2: How to Extract Data from Text file 1 based on the Value from Text file 2
by roborat (Novice) on Mar 04, 2010 at 12:30 UTC
    Hi Rata, Almut and Serv, Thanks a lot for you reply.
    I'll study and try to update the suggested codes.
    Thanks a lot Perl Monks. :)
Re^2: How to Extract Data from Text file 1 based on the Value from Text file 2
by roborat (Novice) on Mar 04, 2010 at 13:24 UTC
    Hi Serf, Thanks a lot, the code is working as I need to. Right Now, I'm trying to put the each customer reports to each separate txt or html file.
    Can please give a hint or show how to do it?
    Thanks a Lot!
      If you change the last block to this it should do what you want.

      Modify the "$output" filename to suit your needs.

      for my $customer ( keys %$cust ) { # If you want to write to a file named with the customer ID # my $output = "./$customer.out"; # If you want to write to a file named with the customer name my $output = "./$cust->{$customer}->{name}.out"; open (CUST_OUT, ">$output") || die "Can't write to '$output': $!\n +"; print CUST_OUT "CUSTOMER NAME: $cust->{$customer}->{name}\n" . "Device_Code Port Traf_Dir Data_Usage\n"; for my $device ( sort by_name keys %{$bill_data->{$customer}} ) { for my $port ( sort keys %{$bill_data->{$customer}->{$device}} + ) { (my $short_port = $port) =~ s/^FastEthernet/Fa/g; for my $direction qw(OUT IN) { print CUST_OUT "$device $short_port $direction " . $bill_data->{$customer}->{$device}->{$port}->{$dir +ection} . $/; } } } close CUST_OUT; }
        Thanks a lot Serf, very much appreaciate your help... I should continue my work from here.

        Thanks again.
        Hi Serf, I was trying to add another column which is the last month period in the report output. I was able to get the last month period like 1 Feb 10 - 28 Feb 10. But when I tried to add the column in the program. The new "Period" column is inserted in a diffent row.

        Current Ouput with new Period Column:

        CUSTOMER NAME: AGD-WEb
        Period Device_Code Port Traf_Dir Data_Usage
        1Feb2010 - 28Feb2010
        SWITCH Fa1_0_33 OUT1.311
        1Feb2010 - 28Feb2010
        SWITCH Fa1_0_33 IN10.716
        1Feb2010 - 28Feb2010
        SWITCH Fa1_0_35 OUT50.796
        1Feb2010 - 28Feb2010
        SWITCH Fa1_0_35 IN7.882
        1Feb2010 - 28Feb2010
        SWITCH Fa2_0_33 OUT-0.000
        1Feb2010 - 28Feb2010
        SWITCH Fa2_0_33 IN-0.000
        1Feb2010 - 28Feb2010
        SWITCH Fa2_0_35 OUT-0.000
        1Feb2010 - 28Feb2010
        SWITCH Fa2_0_35 IN-0.000

        Here's the code I updated with $lastmonth_period (I use DateTime module from CPAN) :) :
        for my $customer ( keys %$cust ) { # If you want to write to a file named with the customer ID # my $output = "./$customer.out"; # If you want to write to a file named with the customer name my $output = "./$cust->{$customer}->{name}.txt"; open (CUST_OUT, ">$output") || die "Can't write to '$output': $!\n +"; print CUST_OUT "Data Transfer Report for $cust->{$customer}->{name +}\n" . "Period Device_Code Port T +raf_Dir Data_Usage\n"; for my $device ( sort by_name keys %{$bill_data->{$customer}} ) { for my $port ( sort keys %{$bill_data->{$customer}->{$device}} + ) { (my $short_port = $port) =~ s/^FastEthernet/Fa/g; for my $direction qw(OUT IN) { print CUST_OUT "$lastmonth_period $device $short_port +$direction" . $bill_data ->{$customer}->{$device}->{$port}->{$di +rection} . $/; } } } close(CUST_OUT); }
        The output I am trying to do should be like:

        CUSTOMER NAME: AGD-WEb
        Period Device_Code Port Traf_Dir Data_Usage
        1Feb2010 - 28Feb2010 SWITCH Fa1_0_33 OUT1.311
        1Feb2010 - 28Feb2010 SWITCH Fa1_0_33 IN10.716
        1Feb2010 - 28Feb2010 SWITCH Fa1_0_35 OUT50.796
        1Feb2010 - 28Feb2010 SWITCH Fa1_0_35 IN7.882
        1Feb2010 - 28Feb2010 SWITCH Fa2_0_33 OUT-0.000
        1Feb2010 - 28Feb2010 SWITCH Fa2_0_33 IN-0.000
        1Feb2010 - 28Feb2010 SWITCH Fa2_0_35 OUT-0.000
        1Feb2010 - 28Feb2010 SWITCH Fa2_0_35 IN-0.000

        Also, I need to get the total Data Usage of each customer, so i need to get the sum. Can please help me on this? Or how should I update the code from here? I'm currently lost right now.
        Thanks a lot!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://826691]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2014-07-11 09:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (223 votes), past polls