用于包装程序并有时附加参数的 Bash 函数

用于包装程序并有时附加参数的 Bash 函数

我对通用解决方案感兴趣,但我的具体示例问题是编写一个.bashrc函数,该函数将grep文件路径包装并附加到命令(如果丢失)。基本上,任何时候 grep 都会等待 stdin,我反而希望它搜索特定文件。我的问题是如何(在包装器中)判断最终参数是否是要搜索的路径,例如搜索模式。

$ ls
example_file.txt
$ grep -someopts 'somestring' 'example_file.txt'

假装这-someopts实际上是 grep 的任意有效选项。
最后一个参数是模式(要搜索)还是文件(要搜索)?
如果somestring是 -选项之一的参数,则example_file.txt是要搜索的模式,并且 grep 将等待标准输入。否则,somestring是要搜索的模式并将example_file.txt被搜索。

在前一种情况下,我想在命令末尾附加要搜索的我自己的文件,但我无法在没有误报的情况下检测到所述情况。唯一的方法似乎是包装器考虑 grep 可以采用的每个参数。

这是我的包装函数(check_has_path我需要实现的地方):

function grep_wrapped() {
    if check_has_path ; then
        grep "$@"
    else
        grep "$@" '/default/filepath.txt'
    fi
}

答案1

方法:将命令行选项与命令行上的模式和可能的文件名分开,然后计算不是选项的命令行参数。如果有多个,请按原样运行命令,否则在文件上标记。

bash

mygrep () {
    local -a opts

    while [ "$#" -gt 0 ]; do
        case "$1" in
            --) opts+=( "$1" ); shift; break ;;
            -*) opts+=( "$1" ) ;;
            *)  break
        esac
        shift
    done

    if [ "$#" -gt 1 ]; then
        grep "${opts[@]}" "$@"
    else
        grep "${opts[@]}" "$@" "/my/file"
    fi
}

该函数将命令行选项与命令行的其余部分分开,并检查是否存在多个非选项命令行参数(即模式以外的参数)。如果没有,您的文件将被标记到命令的末尾。

如果您使用带有选项参数的选项(例如 ),这将不起作用-e PATTERN,因此它有些缺陷。也许它可以作为其他人的起点?


从评论中可以清楚地看出该用户不是对运行grep完全感兴趣,而是对搜索具有特定扩展名的文件感兴趣。

下面的 shell 函数可以做到这一点:

extfind () {
    local ext="$1"

    if [ -z "$ext" ]; then
        echo 'Missing extension' >&2
        return 1
    fi

    shift
    local dir="${1:-$HOME}"

    find "$dir" -type f -name "*.$ext"
}

该函数将用作

$ extfind txt

查找.txt主目录中或主目录下名称以结尾的所有文件,或者

$ extfind "[hc]" /usr/src

查找目录中或目录下名称以 或 结尾的.h所有.c文件/usr/src

答案2

你可以尝试一下 pythonesque,如果有异常就做其他事情。就像是:

function grep_wrapped(){
    grep "$@" <&-
    local rc=$?
    if [ $rc = 2 ]      # probably a read error from closed stdin
    then   grep "$@" /default/filepath.txt
    else   return $rc
    fi
}

它将所有工作留给 grep。这将会产生错误消息的副作用

grep: (standard input): Bad file descriptor

当你从 grep 中得到退出代码 2 时,因为 stdin 已关闭。显然,您可以重定向 stderr 以将其捕获到文件或变量,并在返回代码为 0 或 1 时打印它。

相关内容