Grep:查找调用函数的函数

Grep: Finding in which functions a function is called

假设我有一个包含许多模块的文件夹,并且我正在为一个函数执行 grep。假设我正在搜索的函数名为 test()。是否可以找出调用了哪些函数test()?例如,假设下面是 ModuleA.erl,我们为 test().

做一个 grep
FunctionA()
   A = 5, 
   B = 3,
   test()

应该return:

ModuleA.erl: FunctionA()

可以安全地假设函数定义将始终是非缩进的

您可以使用 awk 来实现:

$ awk -v patt="test" '[=10=] ~ /^\w/ {f=[=10=]} [=10=] ~ patt {print f}' file
FunctionA()

说明

这将存储不以 space 开头的行。如果一行匹配,则打印最后存储的行。

  • -v patt="test" 提供模式
  • [=14=] ~ /^\w/ {f=[=14=]} 如果当前行以某个字符开始(不是 space),存储它的值。
  • [=15=] ~ patt {print f} 如果一行包含给定的模式,打印存储的 header.

测试

$ cat a
FunctionA()
   A = 5, 
   B = 3,
   test()
FunctionB()
   A = 5, 
   B = 3,
   another()
$ awk -v patt="test" '[=11=] ~ /^\w/ {f=[=11=]} [=11=] ~ patt {print f}' a
FunctionA()

只需 运行 在存储 .erl 文件的目录中执行以下 grep 命令。

grep -HPoz '^\S.*(?=(\n .*)+test\(\))' *.erl

来自man grep

-H, --with-filename       print the file name for each match
-P, --perl-regexp         PATTERN is a Perl regular expression
-z, --null-data           a data line ends in 0 byte, not newline

^ 断言我们处于起点。 \S 匹配任何非 space 字符。.* 匹配任何字符但不包括换行符,零次或多次。 (?=(\n .*)+test\(\)) 肯定的先行断言断言匹配后必须跟

  • \n .*一个换行符和一个space后跟任意数量的字符,

  • (\n .*)+ 一次或多次。

  • test\(\) 并且必须有一个 test() 字符串。只有满足这个条件才会匹配。

测试:

Folder$ cat gi.erl
FunctionA()
       A = 5, 
       B = 3,

FunctionB()
       A = 5, 
       B = 3,
       test()
Folder$ cat ri.erl
FunctionA()
   A = 5, 
   B = 3,
   test()
FunctionB()
   A = 5, 
   B = 3,
Folder$ grep -HPoz '^\S.*(?=(\n .*)+test\(\))' *.erl
gi.erl:FunctionB()
ri.erl:FunctionA()

这里Folder是存放所有erl个文件的文件夹名称。