在代码块(regexp)中查找字符串
我需要在代码块(当然可以包含换行符)中找到包含字符串的文件名,或者更具体地说:构造函数中的某些方法调用(我们称之为methodName)。我需要查看当前目录及其子目录中的所有java代码文件 可能的匹配是:在代码块(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
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
来吃掉它。格雷普喜欢找一个匹配的人,而且会的。