在代码块(regexp)中查找字符串

在代码块(regexp)中查找字符串,regex,linux,string,grep,newline,Regex,Linux,String,Grep,Newline,我需要在代码块(当然可以包含换行符)中找到包含字符串的文件名,或者更具体地说:构造函数中的某些方法调用(我们称之为methodName)。我需要查看当前目录及其子目录中的所有java代码文件 可能的匹配是: public myClass() { a(1); b(); myMethod("abc"); c(5); } 这是我到目前为止提出的表达方式: find . -name *.java | xargs nawk '{print $0 "~("FILENAME")"}' | t

我需要在代码块(当然可以包含换行符)中找到包含字符串的文件名,或者更具体地说:构造函数中的某些方法调用(我们称之为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,以便能够在块中使用grep
-然后查找methodName

问题是每次我需要使用。*我都必须将表达式更改为下一个表达式的否定,然后更改为下一个表达式的否定。例如:如果我需要
*\~
,我需要做
([^~]*~
…这不好,但我可以接受。问题来自方法名,因为否定该字符串会更痛苦。


有什么想法吗?可以用regexp完成吗?

代替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
'

你正在与贪婪作斗争。
*
默认情况下会变得贪婪,因此它会尽可能多地消耗,成为一切。只有在它消耗了一切之后,它才会尝试匹配表达式的下一部分
m
,并回溯直到找到为止。如果它找到了模式的其余部分,它将匹配从e第一次出现在
*
('public\w+([^)]*)前面的模式,到最后一次出现在
*
methodName([^~]*([^)]*))后面的模式

解决方案是将
*
设置为惰性:
*?
,为您提供完整的表达式
public\w\+([^]*)。?方法名([^~]*~([^]*)

有趣的是,在使用否定字符类的情况下,使用否定字符类的变通方法是首选的解决方案,但是,是的,使用
methodName
执行类似的操作可能会变得有点笨拙


请看:

我真的很笨吗,还是看起来像是
tr-d“\n”
将所有内容都打印在一行中?@ArjunShankar我想这就是他想要做的。因为“public…methodname..”在原始文件中可能包含换行符。然而,我真的不明白OP要搜索什么。OP:你能不能简化一下,例如,我想在所有java文件中搜索“某物”。你能定义“某物”吗?如果你搜索
*methodName
,那么grep将不会通过匹配
methodName
来吃掉它。格雷普喜欢找一个匹配的人,而且会的。