同样的命令在 bash 中运行良好
git show --pretty="" --name-only HEAD | grep -i .*py
zsh: no matches found: .*py
猛击
git show --pretty="" --name-only HEAD |grep -i .*py
api/client.py
尝试了各种选项,例如使用 退出,传递 -E setopt +o nomatch。
到目前为止什么都没有起作用。
答案1
是关于文件名扩展这发生在 shell 运行之前。发生这种情况的原因是命令中grep
有一个未加引号且未转义的星号 ( )。这种星号是 shell 所特有的。*
当您尝试运行grep .*py
并且没有匹配的文件时.*py
(注意,.*py
在这种情况下不被视为正则表达式,点不是特殊的),基本上会发生两件事:
POSIX 行为是 shell
grep
使用文字.*py
作为参数运行。这就是您想要的。这就是 POSIX shell (sh
) 和兼容 shell 的行为方式。非 POSIX 行为是 shell 检测到不匹配,打印类似以下内容
no matches found: .*py
,并且不运行grep
根本。这是 Zsh 的默认行为。(为了比较:在 Bash 中,您可以通过 切换到此行为shopt -s failglob
。)
如果存在匹配项(在任何 shell 中),例如名为 的文件等,.copy
则将被替换为一个或多个单词作为名称,并且会看到它们,而不是文字字符串。该命令会执行您不想要的操作(比较.foo.py
.*py
grep
.*py
我的这个答案)。即使与 匹配,您也不想进行文件名扩展.*py
。用引号括住字符串以抑制文件名扩展。在这种情况下,*
仅引用或转义就足够了。所有这些都应该有效:
grep -i '.*py'
grep -i ".*py"
grep -i .'*'py
grep -i .\*py
我更喜欢引用整个论点。在某些情况下,其他可能性更有用,知道有多种方法会很好。