geek
geek

Reputation: 816

add a line of text above a matching pattern

I have bunch of .cpp files. say tes1.cpp

 example
//commented
 abc
 def

test2.cpp

efg

test3.cpp

def
efg

I need to write a script,

 find which file has abc pattern, 
  if found need to find if it has //commented pattern, 
    if it is found then find if //additional text,
        if not found then add a line of text //additional comment above //commented 

output file should be, test1.cpp

example
//additional comment
//commented
abc
def

i tried with

if grep -Erl '\babc\b' *; then
   if grep "//commented" ; then
   echo "Already updated"
   else
  sed '\/\/ commented /i\// additional comment' 
  fi
fi

but execution hangs. how do i do it?

edit: editing the command

grep -Erl '\babc\b' * | xargs sed -i '/ commented /i \// additional comment'

but it does not check whether the file already had //additional comment pattern

Upvotes: 2

Views: 73

Answers (3)

potong
potong

Reputation: 58440

This might work for you (GNU sed):

sed -ri -e '/abc/{:a;i//additional comments\n//commented' \
 -e 'b};N;//{:b;\#//commented#{i//additional comments' \
 -e 'b};P;s/.*\n//;ba};N;//{\#^//additional comment#{p;d};P;s/[^\n]*\n//;bb};P;D' file

If a line contains abc insert the two lines of required text. Otherwise, read the next line and if this contains abc, check if first line began //commented and if so, insert the first line of required text and print the other two lines, else print the first line, remove it and then treat the line as if it were the first. Otherwise, check the third line for abc etc.

Upvotes: 0

geek
geek

Reputation: 816

sed:

grep -L ' additional comment' * | 
xargs grep -Erl '\babc\b' | 
xargs sed -i '/ commented /i \// additional comment'

This worked fine.

Upvotes: 0

James Brown
James Brown

Reputation: 37414

In awk:

$ awk 'BEGIN{RS="";FS=OFS="\n"}/abc/{for(i=1;i<=NF;i++)if($i~/\/\//)$i="//addtional comment\n" $i}1' file
 example
//addtional comment
//commented
 abc
 def

Explained:

awk '
BEGIN {
    RS=""                                 # record changes at first empty line
    FS=OFS="\n"                           # field separator is a newline
}
/abc/ {                                   # if record has abc
    for(i=1;i<=NF;i++)                    # iterate all fields
        if($i~/\/\//)                     # at line with comment
            $i="//addtional comment\n" $i # add the addition
}1' file                                  # print

It preceeds a line with // with the //additional comment. Feel free to tune the regex in the if to your liking. This script only processes one file at the time.

Upvotes: 1

Related Questions