java learner
java learner

Reputation: 21

Perl to read the config value properly for comma separated values

Config file:

rb_acc=country of account opening #,Global #,country_account_open
rb_adv=adverse media information #,Global #,adverse_info_flag,adverse_info_severity,adverse_info_date
rb_arm=account relationship manager #,Global #,arm_code,count_of_clients

My reading routine:

sub read_header{    
    open my $header_file, '<', $header_configuration_path or die "Can not open '$header_file': $OS_ERROR"; 
    while (<$header_file>) {        
        chomp;                 
        s/#.*//;               
        s/^\s+//;               
        #s/\s+$//;              
        next unless length;    
        my ($var, $val) = split(/\s*=\s*/, $_, 2);
        $data{$var} = $val;
    }
    close $header_file;

    print "Data values\n";
    print Dumper \%data;

}

My output is coming like:

$VAR1 = {
          'rb_acc' => 'country of account opening
rb_adv=adverse media information #,Global #,adverse_info_flag,adverse_info_severity,adverse_info_date
rb_arm=account relationship manager #,Global #,arm_code,count_of_clients'

        };

But i need something like

rb_acc=>country of account opening #,Global #,country_account_open
rb_adv=>adverse media information #,Global #,adverse_info_flag,adverse_info_severity,adverse_info_date
rb_arm=>account relationship manager #,Global #,arm_code,count_of_clients

Please help.

The split i use is not working i guess i am new to perl.

Upvotes: 1

Views: 74

Answers (1)

zdim
zdim

Reputation: 66899

The one error is in the regex intended to remove comment lines: it needs an anchor; as it stands it finds the first # anywhere on the line and removes it with everything that follows.

Other than that, I don't see how you get the reported output. Perhaps it's something else in the program, since your sub (apparently) picks up some %data from outside scope? Just that possibility is enough of a reminder to always declare your variables in the smallest scope.

The program, with a few other fixes (and some personal preferences)

use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

sub read_header {
    my ($file) = @_; 

    my %data;
    open my $fh, '<', $file or die "Can't open $file: $!";
    while (<$fh>) {
        chomp;    
        s/^\s*#.*//;    
        s/^\s+//;            #/
        next if not length;    
        my ($var, $val) = split /\s*=\s*/; 
        $data{$var} = $val;
    }   
    close $fh;
    return \%data;
}

my $file = shift || die "Usage: $0 config-file\n";

my $data = read_header($file);

dd $data;

prints

{
  rb_acc => "country of account opening #,Global #,country_account_open",
  rb_adv => "adverse media information #,Global #,adverse_info_flag,adverse_info_severity,adverse_info_date",
  rb_arm => "account relationship manager #,Global #,arm_code,count_of_clients",
}

The needed variables -- $file and %data -- are declared and passed (in and out of function), as you should always do. Since in this case there is no need to limit the number of terms that split is to return I removed that.

I use Data::Dump to print data.


  As mob notes, that output can be produced by undefining the input record separator $/, along with s/#.*// which removes the first hash and all else (to the first newline, since the . doesn't match a newline). This means that $/ is undefined elsewhere in the program as a global (instead of being local-ized to that scope), what is likely wrong and need be fixed; using the function from this post in that program would still fail.

Upvotes: 2

Related Questions