2012-07-06 32 views
0

我需要找到包含代码块(其中当然可以包含换行符)中包含字符串的文件的名称,或者更具体地说:构造函数(我们称之为methodName)。我需要查看当前目录及其子目录中的所有java代码文件。查找一段代码中的字符串(正则表达式)

可能的搭配是:

public myClass() { 
    a(1); 
    b(); 
    myMethod("abc"); 
    c(5); 
} 

这是表达我已经想出迄今:

find . -name *.java | xargs nawk '{print $0 "~("FILENAME")"}' | tr -d "\n" | grep -s -i -o 'public \w\+([^)]*).*methodName([^~]*~([^)]*)' 

所以...
- *发现.java文件递归地
- 每行都打印出来,并在其旁边显示它所属的文件名(仅用于跟踪它被发现的位置)
- \ n被删除以便能够o在块中使用grep
- 然后找到方法名

问题是,我每次需要使用*。我必须将表达式更改为否定下一个表达式,然后下一个表达式。例如:如果我需要.*\~,我需要做([^~]*~ ...那不好,但我可以忍受它。问题出在methodName,因为否定该字符串会更痛苦。

任何想法?它可以用正则表达式来完成吗?

+0

难道我真糊涂,还是它看起来像'TR -d“\ n”'基本上将打印* *一切都在一个大线? – ArjunShankar 2012-07-06 21:07:12

+1

@ArjunShankar我想这就是他想要做的。因为“public ... methodname ..”可能在原始文件中包含换行符。但是,我并不真正了解OP将要搜索的内容。 OP:你能简化一下吗?我想在所有的java文件中搜索“东西”。你能定义“东西”吗? – Kent 2012-07-06 21:09:33

+0

如果您搜索'。* methodName',那么grep将不会通过将'methodName'匹配到'。*'来消耗。 Grep喜欢找一场比赛,而且会。 – ArjunShankar 2012-07-06 21:16:55

回答

0

而不是grep,尝试使用sed。这里有一些可以帮助你开始的东西:

find . -name *.java | xargs awk '{print $0 "~("FILENAME")"}' | \ 
sed -n '         # start sed with automatic printing suppressed 
/public \w\+/,/^}/H      # append all constructors to hold space 
$!d          # stop here unless this is the last line 
g           # copy hold space to pattern space 
s/.*methodName([^~]*~(\([^)]*\)).*/\1/p # if methodName is called, print the file name 
' 
1

你在贪婪中挣扎。 .*默认情况下会贪婪,所以它会消耗尽可能多的东西,成为一切。只有在它成为所有东西之后,它才会尝试匹配表达式的下一部分m并返回,直到它结束。如果它发现模式的其余部分,它将匹配.*('public \ w +([^)] *)')之前的模式的第一次出现到.*(后面的模式)后面的最后一次发生methodName([^~]*~([^)]*))。

的解决方案是让.*懒:.*?,让您充分表达public \w\+([^)]*).*?methodName([^~]*~([^)]*)

有趣的是,你使用否定的字符类的解决方法是在你使用它的情况下,首选的解决方案,但是,是的,做类似methodName可能会变得有点笨拙。

参见:Laziness Instead of Greediness

相关问题