Bash,查找内容与搜索字符串匹配的函数

Yor*_*ubs 4 bash text-processing

我想在 bash 中搜索所有定义的函数以查找某些搜索字符串。下面是一个开始,但我想消除下一行中所有后面没有$1空格的术语(即消除在该函数体中找不到的所有条目)。

fu() { declare -f | grep -e \(\) -e $1; }
Run Code Online (Sandbox Code Playgroud)

例如这个输出:

...
tt ()
untargz ()
urlfix ()
ver ()
    [ -f /etc/lsb-release ] && RELEASE="$(cat /etc/lsb-release | grep DESCRIPTION | sed 's/^.*=//g' | sed 's/\"//g') ";
vi. ()
vi.su ()
...
Run Code Online (Sandbox Code Playgroud)

会减少到

...
ver ()
    [ -f /etc/lsb-release ] && RELEASE="$(cat /etc/lsb-release | grep DESCRIPTION | sed 's/^.*=//g' | sed 's/\"//g') ";
...
Run Code Online (Sandbox Code Playgroud)

一个更好的方法(如果可能的话)是如果每个匹配函数都可以被确定并完整显示。

我设想大致如下:

  • 收集函数的名称以及其主体中的搜索字符串(函数的名称始终是匹配项之前的一行中的单个单词,从 at 开始,^后跟一个空格,然后以 结尾的行()$),然后command -V对每个函数使用名称,或者,declare -f再次执行 a,但这一次,使用这些名称并匹配它们之后的所有内容,从{}(其中{}各自在单行上^- 我知道 grep/awk/sed 可以对那些拥有这些知识的人做出惊人的事情。

最终结果将运行,它将向我显示函数体中fu awk包含的每个函数的定义。awk

Adm*_*Bee 5

awk我想到了管道接收端的以下命令:

declare -f | awk -v srch="pattern" 'NF==2 && $2=="()"{if (m) print buf; buf=""; m=0}
                                    buf && index($0,srch){m=1}
                                    {buf=buf ORS $0}
                                    END{if (m) print buf}'
Run Code Online (Sandbox Code Playgroud)

buf这个想法是在解析 的输出时将每个函数的声明和主体存储在缓冲区中declare -f,但仅在找到搜索字符串时才打印缓冲区。

  • 如果程序遇到仅由两个字段(= 空格分隔的“单词”)组成的行,其中第二个字段是 ,则程序将识别新函数定义的开始()。如果在解析前一个函数时找到匹配项(由标志为 1 表示),则将打印m缓冲区。buf缓冲区和标志都将被重置。
  • awk搜索词作为变量传递给程序srch。如果在当前行找到它(函数index返回非零结果),则m标志设置为 1,但前提是我们不在函数声明开始的行上(通过buf不为空来指示),否则匹配函数名称中的内容也算在内。
  • 每行都会被追加到 buffer 中,并通过输出记录分隔符(默认为换行符)buf与之前的内容分隔开。ORS
  • 最后,如果找到匹配,则执行另一次检查,如果找到,则打印缓冲区。如果没有该检查,将永远不会考虑最后一个函数定义。

笔记

index()该程序使用的函数执行全字符串搜索awk。如果您希望搜索基于正则表达式匹配,则需要将条件更改为

index($0,srch)
Run Code Online (Sandbox Code Playgroud)

$0~srch
Run Code Online (Sandbox Code Playgroud)

(但是,一如既往,请注意,搜索包含对正则表达式具有特殊含义的字符的字符串会变得更加麻烦)。