changing values in certain blocks

Discussion in 'Perl Misc' started by alfonsobaldaserra, Feb 3, 2011.

  1. hello again,

    i have a bunch of nagios configuration files. the contents are as
    follows

    define service {
    host_name chakra.example.com
    service_description Disk Monitor
    use disk_service
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    notification_interval 60
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }

    define service {
    host_name chakra.example.com
    service_description Ping
    use ping_service
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    notification_interval 60
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }

    define service {
    host_name chakra.example.com
    service_description SNMP
    use processes_service
    check_command check_snmp_process!community!
    snmp!0
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    check_period xi_timeperiod_24x7
    notification_interval 60
    notification_period xi_timeperiod_24x7
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }

    the value of check_interval for every file is 5. i want to change
    that to 60 but only for "Disk Monitor" blocks which could be anywhere
    in the file. in this post that is at the top. i tried but failed so
    i thought i might get some ideas from here :)

    as always any pointers are appreciated. thank you
    alfonsobaldaserra, Feb 3, 2011
    #1
    1. Advertising

  2. i think i figured a working way to achieve this:

    #!/usr/bin/perl

    use strict;
    use warnings;
    use File::Copy;

    $|++;

    my $file = shift;
    my $new = "${file}\.new";

    open my $conf, "<", $file or die "$!\n";
    local $/ = undef;
    my $eggs = <$conf>;
    close $conf;

    $eggs =~ s/(.*disk_service.*?check_interval\s*)5(.*)/${1}60${2}/s;

    open my $conf2, ">", $new;
    print $conf2 $eggs;
    close $conf2;

    move $file, "${file}\.old";
    move $new, $file;

    __END__

    i am not quite satisfied with $eggs substitution part, i believe there
    should be a better way to do this. thanks.
    alfonsobaldaserra, Feb 3, 2011
    #2
    1. Advertising

  3. alfonsobaldaserra wrote:

    > i have a bunch of nagios configuration files. the contents are as
    > follows
    >
    > define service {
    > host_name chakra.example.com
    > service_description Disk Monitor
    > use disk_service
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > notification_interval 60
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > define service {
    > host_name chakra.example.com
    > service_description Ping
    > use ping_service
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > notification_interval 60
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > define service {
    > host_name chakra.example.com
    > service_description SNMP
    > use processes_service
    > check_command check_snmp_process!community!
    > snmp!0
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > check_period xi_timeperiod_24x7
    > notification_interval 60
    > notification_period xi_timeperiod_24x7
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > the value of check_interval for every file is 5. i want to change
    > that to 60 but only for "Disk Monitor" blocks which could be anywhere
    > in the file. in this post that is at the top. i tried but failed so
    > i thought i might get some ideas from here :)
    >
    > as always any pointers are appreciated. thank you


    Actually, you rather should include "check_interval 60" in the
    "disk_service" template and remove it from the individual service
    definition...

    Helmut
    Helmut Schneider, Feb 3, 2011
    #3
  4. alfonsobaldaserra

    Guest

    On Thu, 3 Feb 2011 10:57:56 -0800 (PST), alfonsobaldaserra <> wrote:

    >i think i figured a working way to achieve this:
    >
    >#!/usr/bin/perl
    >
    >use strict;
    >use warnings;
    >use File::Copy;
    >
    >$|++;
    >
    >my $file = shift;
    >my $new = "${file}\.new";
    >
    >open my $conf, "<", $file or die "$!\n";
    >local $/ = undef;
    >my $eggs = <$conf>;
    >close $conf;
    >
    >$eggs =~ s/(.*disk_service.*?check_interval\s*)5(.*)/${1}60${2}/s;
    >
    >open my $conf2, ">", $new;
    >print $conf2 $eggs;
    >close $conf2;
    >
    >move $file, "${file}\.old";
    >move $new, $file;
    >
    >__END__
    >
    >i am not quite satisfied with $eggs substitution part, i believe there
    >should be a better way to do this. thanks.


    As long as you made an attempt, this might help.

    -sln

    -------------
    use strict;
    use warnings;

    # Regex uses (?(condition)yes-pattern|no-pattern)
    # Probably experimental, shouldn't use it.

    my $rx = qr/
    # Required '{', grp: 1
    ({[^}]+?)

    (?: # Optional, grps: 2,3,4
    ( (?<=\s) check_interval \s+ ) (\d+) (?=\s) ([^}]*?)
    )?
    # Required, grp: 5
    ( (?<=\s) service_description \s+ Disk\ Monitor (?=[\s}]) [^}]*?)

    (?(2)| # Required if grp 2 didn't capture, grps: 6,7
    ( (?<=\s) check_interval \s+ ) (\d+) (?=[\s}])
    )
    /xs;


    my $datastring = join '', <DATA>;

    my $count = $datastring =~ s/$rx/
    $1 .
    (defined $3 ? "${2}60${4}" : '') .
    $5 .
    (defined $7 ? "${6}60" : '')
    /eg;

    print "Changed $count item(s)\n";
    print $datastring,"\n" if $count;

    __DATA__

    define service {
    host_name chakra.example.com
    service_description Disk Monitor
    use disk_service
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    notification_interval 60
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }

    define service {
    host_name chakra.example.com
    service_description Ping
    use ping_service
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    notification_interval 60
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }

    define service {
    host_name chakra.example.com
    service_description SNMP
    use processes_service
    check_command check_snmp_process!community!
    snmp!0
    max_check_attempts 5
    check_interval 5
    retry_interval 1
    check_period xi_timeperiod_24x7
    notification_interval 60
    notification_period xi_timeperiod_24x7
    contacts nagiosadmin
    _xiwizard windows_server
    register 1
    }
    , Feb 3, 2011
    #4
  5. alfonsobaldaserra wrote:
    > hello again,
    >
    > i have a bunch of nagios configuration files. the contents are as
    > follows
    >
    > define service {
    > host_name chakra.example.com
    > service_description Disk Monitor
    > use disk_service
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > notification_interval 60
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > define service {
    > host_name chakra.example.com
    > service_description Ping
    > use ping_service
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > notification_interval 60
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > define service {
    > host_name chakra.example.com
    > service_description SNMP
    > use processes_service
    > check_command check_snmp_process!community!
    > snmp!0
    > max_check_attempts 5
    > check_interval 5
    > retry_interval 1
    > check_period xi_timeperiod_24x7
    > notification_interval 60
    > notification_period xi_timeperiod_24x7
    > contacts nagiosadmin
    > _xiwizard windows_server
    > register 1
    > }
    >
    > the value of check_interval for every file is 5. i want to change
    > that to 60 but only for "Disk Monitor" blocks which could be anywhere
    > in the file. in this post that is at the top. i tried but failed so
    > i thought i might get some ideas from here :)
    >
    > as always any pointers are appreciated. thank you



    perl -i.bak -00pe'/service_description\s+Disk Monitor/ &&
    s/(check_interval\s+)5(?=\s)/${1}60/' yourfile



    John
    --
    Any intelligent fool can make things bigger and
    more complex... It takes a touch of genius -
    and a lot of courage to move in the opposite
    direction. -- Albert Einstein
    John W. Krahn, Feb 4, 2011
    #5
  6. > perl -i.bak -00pe'/service_description\s+Disk Monitor/ &&
    > s/(check_interval\s+)5(?=\s)/${1}60/' yourfile
    >
    > John
    > --



    thank you everyone for your code, one liner and advise :)
    alfonsobaldaserra, Feb 8, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    637
  2. Replies:
    2
    Views:
    506
    bruce barker
    Mar 25, 2008
  3. matt
    Replies:
    1
    Views:
    243
    George Ogata
    Aug 6, 2004
  4. Replies:
    4
    Views:
    104
    Nobuyoshi Nakada
    Apr 24, 2009
  5. SAN CAZIANO
    Replies:
    8
    Views:
    165
    Dr John Stockton
    Oct 15, 2004
Loading...

Share This Page