首页 > 解决方案 > 难以弄清楚如何将通配符字符串参数传递给 bash 函数

问题描述

我有一个我经常使用的 find-grep 命令。在过去的两年里,我一直在策划它并添加更多的东西以使其更有用。最初我把它放在我桌面上的一个文本文件中。我曾经在需要时复制粘贴命令。去年某个时候,我想到将它直接添加到我的 ~/.bashrc 文件中。这是我想出的代码:

findg() {
    if [ "$#" -lt 2 ]; then
        echo "args: (1) File pattern (2) Args to grep"
        return
    fi
    pattern=$1
    file_pattern=$(basename pattern)
    directory_path=$(dirname pattern)

    # Remove the first argument from the list, so you will only be left with GREP arguments.
    shift

    find $directory_path -name "$file_pattern" -exec grep -Hn --color=always -A 5 -B 5 --group-separator=\n=======================\n -E $* {} \;| less -R
}

我尝试以各种方式调用该函数,例如:

findg "$PWD/source_dir/'*.py'" "'special_function\(self'"
findg $PWD/source_dir/"'*.py'" "'special_function\(self'"
findg $PWD/source_dir/"*.py" "'special_function\(self'"
findg $PWD/source_dir/"\*.py" "'special_function\(self'"

在几乎所有情况下,它似乎首先扩展通配符,然后将扩展的输出传递给我的函数调用。如何将字符串传递给我的 bash 函数。

抱歉,如果我似乎对我正在尝试做的事情一无所知,我是 Bash 脚本的新手。

标签: bashshellgrepfind

解决方案


只要您在调用 时正确引用了模式findg,就不需要模式中添加额外的引号。

findg "$PWD/source_dir/*.py" "special_function\(self"

不过,您的函数中的引用确实需要针对正则表达式进行修复。

findg() {
    if [ "$#" -lt 2 ]; then
        echo "args: (1) File pattern (2) Args to grep"
        return
    fi
    pattern=$1
    file_pattern=$(basename "$pattern")
    directory_path=$(dirname "$pattern")

    # Remove the first argument from the list, so you will only be left with GREP arguments.
    shift

    find "$directory_path" -name "$file_pattern" \
         -exec grep -Hn --color=always -A 5 -B 5 \
               --group-separator="\n=======================\n" \
               -E "$@" {} \; | less -R
}

推荐阅读