Boyd
Boyd

Reputation: 451

how to insert text between strings on two successive lines with awk

I have a yaml file with some missing lines (- source and target under example:) where word1 below needs to be fixed but word2 is ok.

 - dyu: word1
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss1
                note: null
                example:
  - dyu: word2
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss2
                note: null
                example:
                  - source: some example source
                    target: some example target
  - dyu: word3

I have used the following to insert the missing text:

awk -i inplace -v data="                  - source:\n                    target:" '/example:/ {f=1} /- dyu:/ && f {print data; f=0}1' $file 

But the problem is it will also insert the text even where it exists. I need to add the missing text exactly between example:\n - dyu, and not between target: something\n -dyu.

Desired output:

 - dyu: word1
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss1
                note: null
                example:
                  - source: 
                    target: 
  - dyu: word2
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss2
                note: null
                example:
                  - source: some example source
                    target: some example target
  - dyu: word3

How can I achieve this?

Upvotes: 1

Views: 169

Answers (2)

Ed Morton
Ed Morton

Reputation: 203169

$ cat tst.awk
example != "" {
    if ( !/- source:/ ) {
        sub(/[^[:space:]].*/,"",example)
        print example "  - source:"
        print example "    target:"
    }
    example = ""
}
$1=="example:" {
    example = $0
}
{ print }

$ awk -f tst.awk file
 - dyu: word1
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss1
                note: null
                example:
                  - source:
                    target:
  - dyu: word2
    alt:
    trans:
      - lang: fr
        detail: null
        speech:
          - type: null
            def:
              - gloss: gloss2
                note: null
                example:
                  - source: some example source
                    target: some example target
  - dyu: word3

Change the regexp !/- source:/ to /- dyu:/ if you prefer and the script will behave the same way with your sample input but IMHO that's less robust than just testing if source exists after example or not.

Upvotes: 1

M. Nejat Aydin
M. Nejat Aydin

Reputation: 10113

This might be what you're looking for:

awk -v data='                  - source:\n                    target:' \
    'f { if (/- dyu:/) print data; f=0 } /example:/ {f=1} 1
     END { if (f) print data }' file

Upvotes: 1

Related Questions