J'écris un script qui grep le nom de classe du fichier java contenant plusieurs classes, s'il contient la fonction principale.
Exemple: Mon fichier contient text.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 } }
La sortie sera: Enfant
car il contient la fonction principale. J'analyse le motif et grep deux lignes avant le motif principal trouvé dans un fichier.
Mon script:
grep -B 2 "public static void main" "text.txt" > sample.txt filen=$(grep -oP '(?<=class )[^ ]*' sample.txt) echo $filen
Mais mon approche se trompe si le code contient comme:
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"); } }
S'il vous plaît, aidez-moi à trouver la bonne approche .
3 Réponses :
Sous Linux, je le ferais comme ceci:
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 toutes les lignes qui contiennent "public class" ou "public static void main". li >
| grep -B1 "public static void main"
: grep la ligne contenant "public static void main" et une ligne avant. | grep '\ '
: Greps la ligne contenant le mot "class". | sed "s /^.* class \ + //; s /. * $ //"
: Débarrassez-vous de tout ce qui se trouve autour du nom de la classe. Remarque \ et
\>
correspondent aux limites des mots. Donc, \
correspond au mot "classe" mais pas "déclassifié".
Pourriez-vous essayer de suivre une fois.
awk '/public static void main>/{print val} /public class/{val=$3}' Input_file
Vous devez mentionner que nécessite GNU awk pour les limites de mots. Personnellement, je me débarrasserais simplement du \>
pour qu'il soit portable pour tous les awks car toute solution basée sur les expressions rationnelles sera de toute façon imprécise. Le . *
dans votre expression rationnelle ne fait rien d'utile btw, il suffit de s'en débarrasser.
Vous pouvez utiliser Perl. Ce qui suit fonctionne pour les deux scénarios. Notez que grep et awk peuvent donner des résultats incorrects lorsque vous avez plus de 2 espaces entre 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 } }
Pas clair, veuillez mentionner comment vous avez besoin de cette sortie avec logique.
@ RavinderSingh13, vous posez des questions sur mon code de script?