我对通用解决方案感兴趣,但我的具体示例问题是编写一个.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 时打印它。