Shiv
Shiv

Reputation: 33

How to substitute a pattern with different strings in multiple files

I'm in the process of adding java annotations to multiple test files. I have to do this for test methods in multiple files for over 100+ places.

Using some scripting/regular expressions, I have got the annotations in place. Remaining part is providing attribute values for these annotations e.g. as in the case below, I need to replace value = "search_pattern" with value="replace_string1" where replace_string1 is the name of function for which the annotation is being added (it appears few lines below the annotation, see the snippet for reference).

Each file can have multiple functions to apply annotations, and there are many such files.

Is there a way to script this?

I haven't found any luck with sed yet and I don't want to do all of this manually.

@Prop(name = "Operation", value = "search_pattern")
...
@Test
public void replace_string1() {
    ...     
 }

@Prop(name = "Operation", value = "search_pattern")
...
@Test
public void replace_string2() {

}

Upvotes: 0

Views: 89

Answers (1)

thanasisp
thanasisp

Reputation: 5975

You can do it with the help of tac which prints the file in reversed order, so we call it again at the end.

tac file | awk '/^public void/ {v=$3; sub(/\(\)/,"",v)}
     /^@Prop\(name = \"Operation\"/ {sub(/search_pattern/,v,$0)} 1' |tac

here you can see for the awk function sub. 1 at the end means to print.

So for example if you want to do it for all *.java in a directory, you can run something like this:

for f in *.java ; do
    tac "$f" | awk '/^public void/ {v=$3; sub(/\(\)/,"",v)}
         /^@Prop\(name = \"Operation\"/ {sub(/search_pattern/,v,$0)}
         1' |tac > temp && mv temp "$f"
done

the last mv command replaces the file without prompt so you must have tested without it before running.

Upvotes: 1

Related Questions