Unix Bash script um kommentare ueber zeilen finden

Hi,

meine unix-bash kentnisse sind leider ziemlich eingerostet, daher kann mir vielleicht jemand aushelfen.

Ich will rekursiv durch Verzeichnisse eines Ordners gehen und alle Java Dateien reporten, welche einen // Kommentar ueber mind. 3 Zeilen haben.

Hintergrund: Tote auskommentierte codestellen finden…

Kann mir jemand nen shell befehl dafuer geben oder mir sagen mit was ich anfangen kann ?!

ich vermute per find/grep kombination…

Dafür gibt’s extra Tools die das etwas verlässlicher finden. Z.B. Sonar.

Es ist zwar eine vielleicht unsaubere Lösung, sie sollte aber dennoch funktionieren: (habe jetzt gelesen, dass rekursiv gesucht werden soll :slight_smile: )
Achtung: Das Beispiel listet alle Dateien auf, in denen ‚///‘ in mind. 3 verschiedenen Orten vorkommt, wird demnächst verbessert…


#!/bin/bash
for file in $(find $1 -iname "*.java");do
        test $(grep -E '///' $file | wc -l) -ge 3 && echo $file
done

sonar ist mir bekannt, aber es geht mir gerade um ein schnelles einmaliges suchen. Ich nehme an, dass geht schneller als Sonar zu installieren, die projekte bauen zu lassen und schauen dass das alles funzt
@exceptionz danke werde ich mal probieren

[QUOTE=exceptionz]Es ist zwar eine vielleicht unsaubere Lösung, sie sollte aber dennoch funktionieren: (habe jetzt gelesen, dass rekursiv gesucht werden soll :slight_smile: )


#!/bin/bash
for file in $(find $1 -iname "*.java");do
        test $(grep -E '///' $file | wc -l) -ge 3 && echo $file
done

[/QUOTE]
Findet das auch nur Kommentare die ueber mehrere Zeilen gehen?
grep funzt doch nur auf einer Zeile…

@maki
Da hast du Recht, das sollte jedoch mit Erweiterung des Scripts (xargs grep o.ä.) leicht zu lösen sein, werde dann, wenn ich wieder Zeit habe, aktualisieren…

Mit pcregrep sollte das ganze wie gewünscht funktionieren. Auf @exceptionz code aufbauend:


#!/bin/bash
for file in $(find $1 -iname "*.java");do
        test $(pcregrep -M '//.*
//.*
//.*' $file | wc -l) -ge 3 && echo $file
done

Nein, das glaube ich nicht. Denn der Punkt matched normalerweise im Multiline-Mode auch ein Newline. Ich poste gleich mal ein Beispiel mit sed, wie es gehen kann :wink:

falls ihr noch dem Geekwahn verfallen seid und eine Loesung findet wollt gerne zu - ich habs nun doch in java geloest :slight_smile:

Nein, das glaube ich nicht.

Funktioniert einwandfrei. (auf meiner Maschine =D)

find . -type f -exec sh -c 'sed -ne "/\s*\/\//N;/
\s*\/\//N;s/\/\/.*
\s*\/\/.*
\s*\/\//match/p" "{}" | grep match >/dev/null' \; -print

Achso, wenn man dem find noch ein -name '*.java' verpasst, dann werden nicht alle anderen Dateien auch noch durchsucht.

Hast du auch mit sowas getestet:

Ehrlich gesagt nein. Also hab ich’s jetzt ausprobiert. Funktioniert aber genauso wie gewünscht. IMHO (falls pcregrep installiert) die schönere Variante als mit sed da besser lesbar.

Wenn man pcregrep nutzt, dann sollte man @schlingel s regexp noch anpassen und vor die // ein \s* stellen.
@schlingel : habs jetzt auch getestet, das Paket kurz nachinstalliert. Dafür verdient meine Lösung einen obfuscation-Award :wink:

So hier noch einmal der Vollständigkeit halber die Lösung mit reinem grep (Auf @schlingel code aufbauend :slight_smile: )


#!/bin/bash
for file in $(find $1 -iname "*.java");do
        test $(grep -Pzo '//.*
//.*
//.*' $file | wc -l) -ge 3 && echo $file
done

Das wc -l mit dem test kann man weglassen, weil grep true zurückgibt, wenn es einen match gab. Man muss die Standardausgabe nur auf /dev/null umleiten. Auch bei der Lösung fehlt wieder das \s*, denn die Kommentare stehen meistens wohl nicht am Zeilenanfang.

Ein etwas übersichtlicherer Einzeiler:

find . -type f -iname '*.java' -exec sh -c 'grep -Pz "//.*
\s*//.*
\s*//" "{}" >/dev/null' \; -print

Falls Checkstyle eh schon im Einsatz ist, dann kann das auch diesen Job übernehmen. Das würde auch in eine typische Buildumgebung für Java passen.

http://checkstyle.sourceforge.net/config_regexp.html

[XML]


[/XML]

Mal ein ungetestetes Beispiel, dass auf

  • beliebige Whitespaces(\s*)
  • DoppelBack-Slash(\\)
  • beliebige Zeichen (.*)
  • linebreak($)
    matcht. Das ganze dreimal hintereinander, wobei auf den letzten Linebreak verzichtet wird.

*** Edit ***

Das vorige Regexp ist leider mist.

[XML]<?xml version="1.0"?>

module> [/XML]

Das findet jetzt Dateien bei denen in drei aufeinanderfolgenden Zeilen Kommentare vorkommen.

@cmrudolph Da hast du Recht mit dem Hinweis \s*.
Vielen Dank :slight_smile: