Search code examples
shellawksed

SED Challenge - Add line on condition


"sed" is giving me a headace, so I post the issue here. And yes, it should be done with sed, to be executed in a script.

https://www.jdoodle.com/a/6ZL5

The idea is to alter a text file that consists of blocks of about 30 lines. Each block starts with "StartLine" is separated form the next by one empty line (AD-search result). Within each block, I need to add the line "AddMe" after the line "AlwaysExists", BUT ONLY if in this block there not already exists a line that contains "NoNoNo". So its adding on condition... As a result, there should be either of those:

StartLine
AlwaysExists
NoNoNo  <--- Not added "AddMe", because "NoNoNo" exists
<Emply line>

StartLine
AlwaysExists
AddMe <--- Added, because NoNoNo here not exists
<Emply line>

The following is probably a working approach, but I cannot finish it so it works:

sed -i '/StartLine/,/^$/{
  <whatever is needed>
}' myfile.ldif

I hope someone can help. Thanks in advance. Chris

EDIT:

sed '/StartLine/,/^$/{
    /NoNoNo/!{
        :loop
        N
        /NoNoNo/!{
            $!b loop
            a\
AddMe
        }
    }
}' /uploads/ldif.txt

...this only adds AddMe once at the bottom...

EDIT #2 Example Input file:

StartLine
Dummy1
AlwaysExists
NoNoNo
Dummy2

StartLine
Dummy1
AlwaysExists
Dummy2

StartLine
Dummy1
AlwaysExists
NoNoNo
Dummy2

StartLine
Dummy1
AlwaysExists
Dummy2

Solution with awk: I needed to change the script, because of a small missunderstanding. But the approach as suggested by @Luuk is still working! Thanks at you all for giving me that hint!

awk '
  BEGIN{ x=0 }
    function prut() {
      for(i=0; i < length(s); i++) {
        print s[i]
        if (a!=1 && s[i]~/InsertHere/) {
          print "Addme"
          a=0
          }
      }
      x=0; a=0;  delete(s)
    }
    {s[x]=$0; x++}
    /NoNoNo-/{a=1}
    {
      if (length($0)<2){
        prut()
      }
    }
  END {
      prut()
  }
  ' file.ldif

Solution

  • UPDATED (Because of an extended LDFIF.txt):

    When having an input file like:

    StartLine
    Dummy1
    AlwaysExists
    NoNoNo
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    NoNoNo
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    Dummy2
    

    I would use:

    awk 'BEGIN{ x=0 }
         function prut() {
             for(i=1; i<=length(s); i++) {
                 print s[i]
                 if  (a!=1 && s[i]~/AlwaysExists/) {
                     print "AddMe"
                     a=0
                 }
             }
             x=0; a=0;  delete(s)
         }
         /StartLine/{ x=1 }
         (x>0) && /NoNoNo/ { a=1 }
         (x>0){ s[x]=$0; x++ }
         length($1)<2{
             prut()
         }
         END {
             prut()
         }
        ' ldif.txt | sed -e ''
    

    It produces:

    StartLine
    Dummy1
    AlwaysExists
    NoNoNo
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    AddMe
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    NoNoNo
    Dummy2
    
    StartLine
    Dummy1
    AlwaysExists
    AddMe
    Dummy2
    

    and it even includes a use of sed.... 😁😉🤔😕