Grepping class name if contains main function by bash script

Viewed 284

I am writing script that grep the class name of java file containing multiple class, if it contains main function. Example: My file contain text.txt

class Parent 
{
    public void p1()
    {
        System.out.println("Parent method");
    }
}
public class Child extends Parent {

    public static void main(String[] args)
    {
        Child cobj = new Child();
        cobj.c1();   //method of Child class
        cobj.p1();   //method of Parent class
    }
  public void c1()
    {
        System.out.println("Child method");
    }
}  

Output will be: Child because it conatins main function. I analyze the pattern and grep two line before the pattern main found in a file. My script:

grep  -B 2 "public static void main" "text.txt" > sample.txt
filen=$(grep -oP '(?<=class )[^ ]*' sample.txt)
echo $filen

But my approach gets wrong if code contains like:

class Parent
{
    public void p1()
    {
        System.out.println("Parent method");
    }
}
public class Child extends Parent {
    public void c1()
    {
        System.out.println("Child method");
    }
    public static void main(String[] args)
    {
        Child cobj = new Child();
        cobj.c1();   //method of Child class
        cobj.p1();   //method of Parent class
    }
}

Please help me in finding correct approach.

3 Answers

Could you please try following once.

 awk '/public static void main>/{print val} /public class/{val=$3}' Input_file

On Linux I would do it like this:

grep -e 'public class\|public static void main\>' text.txt  | grep -B1 "public static void main" | grep '\<class\>' | sed "s/^.*class \+//;s/ .*$//"
  • grep -e 'public class\|public static void main\>' text.txt: Grep all lines that either contain "public class" or "public static void main".
  • | grep -B1 "public static void main": grep the line containing "public static void main" and one line before.
  • | grep '\<class\>': Greps the line containing the word "class".
  • | sed "s/^.*class \+//;s/ .*$//": Get rid of everything around the class name.

Note \< and \> match word boundaries. So \<class\> matches the word "class" but not "declassified".

You can use Perl. The below works for both scenarios. Note that grep and awk may give incorrect results when you have more than 2 spaces between public/static/class etc

$ perl -0777 -ne ' /\bpublic\s+class\s+(\S+).+?public\s*static\s*void\s*main/ms and print "$1\n" ' arya2.txt
Child

$ cat arya2.txt
class Parent
{
    public void p1()
    {
        System.out.println("Parent method");
    }
}
public class Child extends Parent {
    public void c1()
    {
        System.out.println("Child method");
    }
    public static void main(String[] args)
    {
        Child cobj = new Child();
        cobj.c1();   //method of Child class
        cobj.p1();   //method of Parent class
    }
}
Related