如何打印出包含特定字符串的任何函数的完整函数声明?

too*_*ley 4 bash shell-script text-processing function

我的 中有很多函数bashrc,但是对于新创建的函数,我经常忘记函数的名称。

例如,当我在我的中定义了这个函数时.bashrc

function gitignore-unstaged
{
    ### Description:
    # creates a gitignore file with every file currently not staged/commited.
    # (except the gitingore file itself)
    ### Args: -

    git ls-files --others | grep --invert-match '.gitignore' > ./.gitignore

}
Run Code Online (Sandbox Code Playgroud)

我想要另一个函数来打印函数的定义,如:

$ grepfunctions "gitignore"
function gitignore-unstaged
{
    ### Description:
    # creates a gitignore file with every file currently not staged/commited.
    # (except the gitingore file itself)
    ### Args: -

    git ls-files --others | grep --invert-match '.gitignore' > ./.gitignore
}
Run Code Online (Sandbox Code Playgroud)

但不是匹配“gitignore”,我希望它匹配和之间的每个字符串,因此并且应该输出完全相同的内容。这也是为什么声明 -f 等不能解决问题的原因funtction}$ grepfunctions "###"$ grepfunctions "creates"

我试过的

  • 我不能使用grep
  • 我知道,这会sed -n -e '/gitignore-unstaged/,/^}/p' ~/.bashrc打印出我想要的 - 但sed -n -e '/creates/,/^}/p' ~/.bashrc不是。相反,我收到:

        # creates a gitignore file with every file currently not staged/commited.
        # (except the gitingore file itself)
        ### Args: -
    
        git ls-files --others | grep --invert-match '.gitignore' > ./.gitignore
    }
    
    Run Code Online (Sandbox Code Playgroud)

    函数名和第一个{都被剪掉了,这不是我想要的。

如何打印出包含特定字符串的任何函数的完整函数声明?当然,除了 sed 之外的其他工具也是允许的。

Sté*_*las 5

请注意,使用zsh,您可以执行以下操作:

 printf '%s() {\n%s\n}\n\n' ${(kv)functions[(R)*gitignore*]}
Run Code Online (Sandbox Code Playgroud)

从当前定义的函数中检索信息(显然不包括注释)。

现在,如果您想从源文件中提取信息,那么除非您实现完整的 shell 解析器,否则您无法可靠地进行操作。

如果您可以对函数的声明方式做出一些假设,例如,如果您始终使用该 ksh 样式的函数定义,function并且}在行的开头和在行的开头,您可以执行以下操作:

perl -l -0777 -ne 'for (/^function .*?^\}$/gms) {
  print if /gitignore/}' ~/.bashrc
Run Code Online (Sandbox Code Playgroud)

或者只查看函数体:

perl -l -0777 -ne 'for (/^function .*?^\}$/gms) {
  print if /\{.*gitignore/s}' ~/.bashrc
Run Code Online (Sandbox Code Playgroud)