我在.zshrc中定义了一个函数,如下所示:
fdtnxg () {
find $1 -type $2 -name "$3" | xargs grep "${@:4}"
}
如果我想在当前目录中名称以开头的所有文件中使用fdtnxg
grep ,我必须使用.alias mot
tt.
fdtnxg . f "tt.*" "alias mot"
我想fdtnxg . f tt.* alias mot
直接使用,但是不能。有什么办法让它按照我的预期工作吗?
我试图改变fdtnxg
的是:
fdtnxg () {
find $1 -type $2 -name "\"$3\"" | xargs grep "${@:4}"
}
我尝试了这个,因为echo "\"123\""
我得到了报价"123"
。
答案1
我认为你这里有两个问题。
首先,您要防止 shell 在运行该函数时使用通配符。您不能通过在函数内添加引号来做到这一点,因为文件名在运行之前会扩展为函数的参数。要防止文件名扩展,请运行该函数noglob fdtnxg
,该函数可以使用别名 ( alias fdtnxg="noglob fdtnxg"
) 自动执行。
二、grep的参数。我假设您希望从第四个开始的函数参数连接到 grep 的单个字符串。"${@:4}"
,将它们扩展为不同的单词(就像"$@"
所有位置参数一样)。"$*"
相反,将参数连接到单个字符串。在 Zsh 中,"${*[4,-1]}"
似乎可以连接第四个及后面的参数。 ("${*:4}"
将它们全部连接起来并从第四个开始特点,这与 Bash 的做法不同。)如果这不起作用,您可以随时将前三个移出,然后使用"$*"
.
所以要么
fdtnxg () {
find "$1" -type "$2" -name "$3" -exec \
grep -- "${*[4,-1]}" /dev/null {} +
}
或者
fdtnxg () {
local dir=$1
local type=$2
local name=$3
shift 3
find "$dir" -type "$type" -name "$name" -exec \
grep -- "$*" /dev/null {} +
}
和
alias fdtnxg="noglob fdtnxg"
无论如何,您不能像那样通过管道输出find
to xargs
。您需要-print0
/ -0
GNU 扩展名,或者在这里更好,我们使用标准-exec cmd {} +
查找语法(添加一个/dev/null
参数以确保即使只找到一个文件grep
也始终打印文件名;使用 GNU ,您也可以使用该选项) 。find
grep
-H