René Bello René Bello - 2 months ago 7
Linux Question

PERL extract a values from a config file

I try to extract a group of values, in this case all the ips belonging to allowed_hosts in a config file in my linux system.
so i have this:

configApp.cfg
bla bla bla
...
allowed_hosts = 10.121.120.163,10.121.120.164, ips, ips, more ips ...
...
something .


I already read the web page http://perlmaven.com/how-to-extract-strings-from-a-file

but i have some issues with my scrip.

open(my $file, '<:encoding(UTF-8)', $config_file)
or die "Could not open file '$config_file' $!";
while (my $row = <$file>) {
chomp $row;
my @strings = $row =~ /[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/g;
foreach my $s (@strings){
print "'$s'";
}
}


i hope can help me with the regex expression. Thanks

Answer

Here is another way to do it, given your specific problem

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

my $file = 'configApp.cfg';

open my $fh, '<', $file or die "Can't open $file: $!";

my @allowed_hosts;

while (<$fh>) 
{
    if (/^allowed_hosts\s*=\s*(.*)/) 
    { 
        my @hosts = split /\s*,\s*/, $1; 
        push @allowed_hosts, \@hosts;
    }   
}

# Process hosts as needed
say "@$_" for @allowed_hosts;

Comments

  • Process only the lines which have the needed /^allowed_hosts/

  • Use the captured pattern, available in $1

  • Store the array with results for a line as a reference on an array with all results

  • If there is certainly only one /^allowed_hosts/ line then there is no need for another array – store return from split directly into the @allowed_hosts declared outside of the loop. Then you may as well exit the loop once this line is parsed.

With multiple lines (or files), we can also use an anonymous array

if (/^allowed_hosts\s*=\s*(.*)/) 
{ 
    push @allowed_hosts, [ split /\s*,\s*/, $1 ];
}

However, then we cannot check the result before we stash it away, while with intermediary @hosts you can add checks or further processing/selection if needed.

With the exact text you posted this prints

10.121.120.163 10.121.120.164 ips ips more ips ...