-1

I want to print the lines within { and } with assign where "mango" in Hostgroups

   object Host "os.google.com" {
    import "windows"
    address = "linux.google.com"
    groups = ["linux"]
    }

    object Host "mango.google.com" {
    import "windows"
    address = "mango.google.com"
    groups = ["linux"]

    assign where "mango" in Hostgroups
    }

Desired output:

    object Host "mango.google.com" {
    import "windows"
    address = "mango.google.com"
    groups = ["linux"]

    assign where "mango" in Hostgroups
    }
jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    You'd probably be better off with something designed to parse Icinga configs, instead of trying to hack together a shell solution that will probably have problems in edge cases with escaped brackets/whitespace/etc. – Joseph Sible-Reinstate Monica Jun 22 '19 at 17:59
  • 2
    duplicate of the same question. https://stackoverflow.com/questions/56715510/print-a-specific-words-till-matched-string-pattern-2-above-the-matched-string/56715763#56715763 . Edit your former question if there is a change. – Dudi Boy Jun 22 '19 at 19:36
  • 1
    Possible duplicate of [Print a specific words till matched string ( pattern 2 )above the matched string ( pattern 1 ) in a file](https://stackoverflow.com/questions/56715510/print-a-specific-words-till-matched-string-pattern-2-above-the-matched-string) – Walter A Jun 22 '19 at 21:48

3 Answers3

0

Try this awk script

script.awk

/{/,/}/ { #define record range from { to }
    if ($0 ~ "{") rec = $0; # if record opening reset rec variable with current line
    else rec = rec "\n" $0; # else accumulate the current line in rec
    if ($0 ~ /assign where "mango" in Hostgroups/) { # if found exit pattern in current line
        print rec; # print the rec
        exit;      # terminate
    }
}

executions:

awk -f script.awk input.txt

output:

object Host "mango.google.com" {
import "windows"
address = "mango.google.com"
groups = ["linux"]

assign where "mango" in Hostgroups
Dudi Boy
  • 4,551
  • 1
  • 15
  • 30
0

This might work for you (GNU sed):

sed -n '/{/h;//!H;/}/{g;/assign where "mango" in Hostgroups/p}' file

Turn off seds automatic printing using the -n option and gather up lines in the hold space between curly braces. Following the closing curly brace, replace it with the contents of the hold space and if there is a match for assign where "mango" in Hostgroup print it.

potong
  • 55,640
  • 6
  • 51
  • 83
  • The Linux tag was removed (for an unknown reason). You should supply a non-GNU answer. – jww Jun 23 '19 at 01:45
  • @jww as far as I am aware, this solution will work for the majority of seds out there in the wild. However as I have only tested it using the GNU version I feel it is necessary to provide the qualified message. – potong Jun 23 '19 at 08:19
  • Solaris results in *`sed: command garbled: /{/h;//!H;/}/{g;/assign where "mango" in Hostgroups/p}`*. OS X results in *`sed: 1: "/{/h;//!H;/}/{g;/assign ...": extra characters at the end of p command`*. – jww Jun 23 '19 at 14:16
  • @jww I am surprised and saddened that my solution using sed on Solaris and OS X behave as they do but I can only reiterate `might work for you` in my defence. BTW perhaps those OS's prefer each command separately and this can be achieved using the `-e` option and removing the `;`'s or by puting each command on a separate line in a file and using the `-f` option. – potong Jun 23 '19 at 22:01
  • The above one is working , but its not working when there are {{}} – Haridvpsk Dec 02 '22 at 13:13
0

Assuming } doesn't appear in any other context in your input:

$ awk -v RS='}' '
    /assign where "mango" in Hostgroups/ {
        sub(/^[[:space:]]+\n/,"")
        print $0 RS
    }
' file
    object Host "mango.google.com" {
    import "windows"
    address = "mango.google.com"
    groups = ["linux"]

    assign where "mango" in Hostgroups
    }
Ed Morton
  • 188,023
  • 17
  • 78
  • 185