bhushanQA has asked for the wisdom of the Perl Monks concerning the following question:

I am having below INI file
[Voice_Digit] BASIC_testcase.txt # this is my test case name which i Need to dig ou +t and store as variable
I tried using config::INIFiles module but no success since the INI file format is bit different. Need help how to read the same.

Replies are listed 'Best First'.
Re: Read INI file
by FreeBeerReekingMonk (Deacon) on Apr 05, 2016 at 07:57 UTC
    So your ini file contains .txt filenames to other ini data or do you want to construct your data like so?
    $DATA{"VOICE_DIGIT"} = "BASIC_testcase.txt";

    And then, can there be multiple entries? Tell us more about your format.

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; open(INFH, "<", "a.ini") or die $!; my %INI; my $HEADER = "_"; while(<INFH>){ chomp; s/\s*#.*//; s/^\s+//; s/\s+$//; next unless $_; if(/^\[(\S+)\]$/){ $HEADER = uc($1); next; } $INI{$HEADER} = $_; } close(INFH); print Dumper(\%INI);

    output:

    $VAR1 = { 'Voice_Digit' => 'BASIC_testcase.txt' };
      Hi Thanks for the reply, My .ini file is
      [Test_suit_name] Testcase1.txt
      Basically, this ini file have many test suits and under that many test cases I want to select the test cases based on test suits. Hope this clears.
        use strict; use warnings; open my $fh, '<', 'an.ini' or die "Failed to open an.ini for reading: +$! <$^E>\n"; my (%settings, $head); while (chomp(my $line = <$fh>)) { if ($line =~ /^\s*\[([^\[\]]+)\]\s*$/) { $head = $1; } elsif ($line !~ /^\s*$/) { push @{$settings{$head}}, $line; } } close $fh; use Data::Dumper; print Dumper \%settings;
        Building on SimonPratt's work:

        #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my $VERBOSE; my @TESTSUITES; my %TESTCASES_hash; my @TESTCASES; GetOptions ( "testsuite=s" => \@TESTSUITES, "verbose" => \$VERBOSE ); # Often it is useful to allow comma-separated lists of values as well +as multiple occurrences of the options. @TESTSUITES = split(/\s*,\s*/,join(',', @TESTSUITES)); open my $fh, '<', 'an.ini' or die "Failed to open an.ini for reading: +$! <$^E>\n"; my (%settings, $head); while (chomp(my $line = <$fh>)) { if ($line =~ /^\s*\[([^\[\]]+)\]\s*$/) { $head = $1; } elsif ($line !~ /^\s*$/) { push @{$settings{$head}}, $line; } } close $fh; for my $suite (@TESTSUITES){ for my $test (@{$settings{$suite}}){ $TESTCASES_hash{$test}++; } } @TESTCASES = sort keys %TESTCASES_hash; use Data::Dumper; print Dumper \%settings; print Dumper \@TESTCASES; for my $testcase (@TESTCASES){ # now iterate through your testcases }

        Which would work like:

        ./an.pl -t Test_suit_name ./an.pl -t Test_suit_name -t AnotherTest_suit_name ./an.pl -t Test_suit_name,AnotherTest_suit_name

        latter two are the same, multiple testsuites are merged to produce a bigger list of testcases.

        Hope this extra push in the back helps you...

        Hi, Any clue on this ?
Re: Read INI file
by 1nickt (Canon) on Apr 05, 2016 at 14:12 UTC

    Hi bhushanQA,

    Reading from a config file is a common task. If you've come up with a format that is difficult to process, change it, to standard INI-format, or YAML, or something that one of the many existing tools can read with no modification.

    Change your format to a normal Windows-style ini file and you can use Config::Tiny:

    Config file contents:

    VoiceDigit = BASIC_testcase.txt [mySubSection] foo = bar
    Script:
    use strict; use warnings; use feature 'say'; use Config::Tiny; my $conf = Config::Tiny->read('1159584.ini'); say $conf->{_}->{'VoiceDigit'}; say $conf->{'mySubSection'}->{'foo'}; __END__
    Output:
    BASIC_testcase.txt bar

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Read INI file
by Anonymous Monk on Apr 05, 2016 at 07:58 UTC
      Looking at the grammar in the documentation, it doesn't seem to support values without the assignment operator.

      ini-file = { <section> | <empty-line> } empty-line = [ <space> ] <line-ending> section = <section-header> { <value-assignment> | <empty-line> +} section-header = [ <space> ] "[" <section-name> "]" [ <space> ] <line- +ending> section-name = string value-assignment = [ <space> ] <property-name> [ <space> ] "=" [ <space> ] <value> [ <space> ] <line-ending> property-name = string-without-equals value = string

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        Simple solution, subclass and "handle" it instead of throwing error