Siva Kumar
Siva Kumar

Reputation: 2006

Search and Append with new line Linux

        protected void setUp() throws Exception
        {

              //...
        }

I would like to add @Before for every method in all classes. I have nearly 500+ classes. If I do manually it will be very tough.

        @Before
        protected void setUp() throws Exception
        {

              //...
        }

I have tried this

sed -i "s/protected void setUp()/@Before()\nprotected void setUp()/g" File

But If I do this alignment changed.

    @Before()
protected void setUp() throws Exception
    {

    }

Please help me . I would like to have proper alignment

Upvotes: 3

Views: 56

Answers (3)

Marek Nowaczyk
Marek Nowaczyk

Reputation: 257

I think there is nothing wrong in sed with that simple task:

sed -r -i -e "s/^([ \t]*)(protected void setUp())/\1@Before()\n\1\2/g" File
  • Remember to add -r parameter to activate regex syntax in sed,
  • Use `^([ \t]*)' to get indent,
  • Apply indent before inserted decorator, and also before original line.

Upvotes: 0

fedorqui
fedorqui

Reputation: 290075

With GNU awk you can use gensub() to capture the number of spaces in front of protected void setUp() and print them in front of the desired text:

$ awk '{$0=gensub(/^(\s*)(protected void setUp)/, "\\1@Before\n&", 1)}1' file
        @Before
        protected void setUp() throws Exception
        {
              //...
        }

See how this works:

  • $0=gensub()
    perform the changes and set the current record to this value.
  • gensub(/^(\s*)(protected void setUp)/, "\\1@Before\n&", 1)
    this looks for the string protected void setUp with some spaces in the beginning and captures both. Then, it replaces it with those spaces + "@Before", followed by a new line and the original line.
  • 1
    it triggers the awk's default action, consistent in printing the current (updated) line.

Note this just checks up to protected void setUp. If you also want to check the parentheses after setUp, say: /^(\s*)(protected void setUp\(\))/ (escaping the parentheses is required, since normal ones have the function of capturing groups).

This takes into account that captured groups can be used by saying \\n, being n its ordinal, or & for the full string.


See it in action with more extreme sample file:

 $ cat a
        protected void setUp() throws Exception
        {

              //...
        }

blablablabla
 protected void setUp() throws Exception

and this is
               protected void setUp() throws Exception

It becomes:

$ awk '{$0=gensub(/^(\s*)(protected void setUp)/, "\\1@Before\n&", 1)}1' a
        @Before
        protected void setUp() throws Exception
        {

              //...
        }

blablablabla
 @Before
 protected void setUp() throws Exception

and this is
               @Before
               protected void setUp() throws Exception

Upvotes: 4

Ed Morton
Ed Morton

Reputation: 204035

sed is for simple substitutions on individual lines, that is all. That's not what you are trying to do so it's not a job for sed, it's a job for awk. This will work in any awk:

$ awk '{s=$0} sub(/protected void setUp().*/,"@Before",s){print s} 1' file
        @Before
        protected void setUp() throws Exception
        {

              //...
        }

Borrowing @fedorqui's more comprehensive sample input file:

$ cat a
        protected void setUp() throws Exception
        {

              //...
        }

blablablabla
 protected void setUp() throws Exception

and this is
               protected void setUp() throws Exception

$ awk '{s=$0} sub(/protected void setUp().*/,"@Before",s){print s} 1' a
        @Before
        protected void setUp() throws Exception
        {

              //...
        }

blablablabla
 @Before
 protected void setUp() throws Exception

and this is
               @Before
               protected void setUp() throws Exception

Upvotes: 2

Related Questions