VladoPortos
VladoPortos

Reputation: 603

Insert text before the last line betweeen two matches in sed or awk

I'm having file like this:

subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
    }

this can repeat just with different "types"

I would like t insert something right before the last } in the "set"

So it would look like ( not sure if awk or sed can somehow detect how many spaces have the line before :D ):

subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
        something
    }

I can match it with

sed "/type.*.car.*/,/\} .... something here..."

file I just can't figure it out.. I cant look for "wheels" as that can be something different. Any help would be much appreciated.

Upvotes: 1

Views: 360

Answers (3)

Dudi Boy
Dudi Boy

Reputation: 4865

Here is another awk script (standard Linux gawk).

script.awk

/ +set {/,/ +}/{
    if($0 ~ /type "car"/ ) f = 1; 
    if($0 ~ / +}/ && f == 1) {
        print "        something";
        f = 0;
    }
}1

input.txt

subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
    }
    set {
        type "baot"
        product "nice"
        dealer "here"
        features "1"
        wheels 0
    }
    set {
        type "horse"
        product "too"
        dealer "very"
        features "2"
        wheels 0
    }
}

running:

awk -f script.awk input.txt

output:

subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
        something
    }
    set {
        type "baot"
        product "nice"
        dealer "here"
        features "1"
        wheels 0
    }
    set {
        type "horse"
        product "too"
        dealer "very"
        features "2"
        wheels 0
    }
}

Upvotes: 0

potong
potong

Reputation: 58371

This might work for you (GNU sed):

sed '/\<type\>.*\<car\>/{h;:a;n;/^\s*}/!ba;x;s/\S.*/something/;G}' file

Look for a line containing the required type, copy that line and then read/print subsequent lines until one that begins with a right curly brace. Swap back to the copied line and replace everything from the first non-space with the required string, append the line containing the right curly brace and print the result.

Upvotes: 1

Toto
Toto

Reputation: 91385

Given:

subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
    }
    set {
        type "second"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
    }

If you want to add "something" only when`type "car", run this:

perl -0777 -ape 's/set\h*{[^}]*type "car"[^}]*\K(?=\n\h+})/\n\tsomething/g' file.txt 
subset {
    set {
        type "car"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
        something
    }
    set {
        type "second"
        product "ww"
        dealer "something"
        features "0"
        wheels 4
    }

Explanation:

s/          # substitute
  set           # literally
  \h*           # 0 or more horizontal spaces
  {             # opening curly brace
  [^}]*         # 0 or more non curly brace
  type "car"    # literally
  [^}]*         # 0 or more non curly brace
  \K            # forget all we have seen until this position
  (?=\n\h+})    # positive lookahead, make  sure we have after a linefeed and some horizontal spaces and a closing curly brace
/           # with
  \n            # linefeed
  \t            # a tab
  something     # whatever you want
/g          # end subs, global

Upvotes: 0

Related Questions