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

I am working on SLES ifcfg file and there is a entry of parameter BONDING_MODULE_OPTS='mode=1 miimon=100 primary=p3p1 primary_reselect=1'. I tried using split function to split based on "=" but I want to extract values of mode miimon primary and primary_reselect and store it in a hash. Also other parameters in ifcfg have single entry like IPADDR. I am iterating through file and storing these values in a hash as key value. I need to extract for BONDING_MODULE_OPTS and store these in that hash. I am not getting how do I do it

FILE BONDING_MASTER='yes' BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=p6p2 primar +y_reselect=1' BONDING_SLAVE0='x' BONDING_SLAVE1='y' BOOTPROTO='static' BROADCAST='' ETHTOOL_OPTIONS='' IPADDR='' MTU='' NAME='Bond1' NETMASK='255.255.0.0' NETWORK='' REMOTE_IPADDR='' STARTMODE='none' USERCONTROL='no'

Replies are listed 'Best First'.
Re: Extracting strings around comparision operator
by BrowserUk (Patriarch) on Aug 20, 2015 at 05:18 UTC

    You can use the rarely used third parameter to split to limit the number of elements extracted from the string:

    $s = q[BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=p6p2 + primary_reselect=1'];; ( $key, $value ) = split '=', $s, 2;; print "<$key> <$value>";; <BONDING_MODULE_OPTS> <'mode=active-backup miimon=100 primary=p6p2 pri +mary_reselect=1'>

    Update: If you need to further split the value into a hash then you could do it this way:

    $s = q[BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=p6p2 + primary_reselect=1'];; ( $key, $value ) = split '=', $s, 2;; print "<$key> <$value>";; <BONDING_MODULE_OPTS> <'mode=active-backup miimon=100 primary=p6p2 pri +mary_reselect=1'> $h{$key} = { map{ split '=', $_ } split ' ', substr $value, 1, -1 };; pp %h;; ( "BONDING_MODULE_OPTS", { miimon => 100, mode => "active-backup", primary => "p6p2", primary_reselect => 1, }, )

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
    I'm with torvalds on this Agile (and TDD) debunked I told'em LLVM was the way to go. But did they listen!

      Thank you BrowserUk it is something haven't been used for so long that I almost forgot about it. The issue is resolved

Re: Extracting strings around comparision operator
by Monk::Thomas (Friar) on Aug 20, 2015 at 07:32 UTC

    I was going to suggest 3-args split, but BrowserUK already did that. So here's another way using a regexp:

    ... if ($line =~ /^(\w+)=(["'])(.*)\2$/) { my $key = $1; my $value = $3; ... }

    Basically it does the same as the 3-args split, but additionally it strips the quotes. (\2 refers to (["']) and makes sure the quotes are balanced)

      speaking of which :)
      if( my( $key, undef, $value ) = $line =~ /^(\w+)=(["'])(.*)\2$/) { ...

        I would not write it that way. To me it feels like the matching is made something of an afterthought because it is 'hidden' in the second half of the line. So I wouldn't use that style. It's similar to

        open ......stuff....more stuff......... or die $! vs. open ......stuff....more stuff......... or die $!

        (Basically I like to make it hard to overlook something important when glancing at some piece of code. Even if that results in a slightly increased line count.)