Ben*_*min 2 bash zsh wildcards
我有这个文件树:
a.py
b/c.py
Run Code Online (Sandbox Code Playgroud)
在 Bash 中,ls -l **/*.py
给出
b/c.py
Run Code Online (Sandbox Code Playgroud)
在 Zsh 中,ls -l **/*.py
给出了一个很好的
a.py
b/c.py
Run Code Online (Sandbox Code Playgroud)
有没有办法改变 bash 行为以避免这样做ls *.py **/*.py
?
PS:我用过ls
,但问题是针对任何命令
在 plain sh 和与 plain sh 向后兼容的 shell 中,模式**
和*
是等效的。Zsh 在几个方面偏离了 sh 兼容性,其中之一是模式**/
和***/
递归通配符。**/\xe2\x80\xa6
搜索当前目录、其子目录、其子子目录等***/\xe2\x80\xa6
类似,但也会遍历到子目录的符号链接。
您可以在 bash \xe2\x89\xa54.3 中使用 启用类似功能shopt -s globstar
,在 ksh93 中使用set -o globstar
/启用类似功能set -G
。其他相关选项有:
shopt -s dotglob
使通配符模式匹配点文件(类似于zsh 中的set -o dotglob
/)。\nglobdots
GLOBIGNORE
变量bash
也会自动启用该选项\xc2\xb9。FIGNORE=.:..
。(D)
模式后面的 glob 限定符来完成。Bash/ksh93没有类似的功能。shopt -s extglob
启用 ksh88 样式的扩展 glob 运算符(类似于set -o kshglob
zsh 中的)(在 ksh 中始终启用)。\nset -o extendedglob
一种用不同语法表达任意正则表达式(使用否定运算符)的替代方法。Bash 没有与该语法等效的语法。shopt -s nocaseglob
使模式匹配不区分大小写(类似于zsh 中的set -o nocaseglob
/)。\nset +o caseglob
(#i)
. 类似地,在 ksh93 中,您可以为模式添加前缀~(i)
. Bash 没有类似的功能。shopt -s nullglob
如果没有文件匹配,则将 glob 模式扩展为空列表,而不是保持模式不变(类似于set -o nullglob
zsh)。\n(N)
模式后面的 glob 限定符来完成。在 ksh93 中,放在~(N)
模式之前。Bash 没有类似的功能。shopt -s failglob
如果没有文件匹配则触发错误,而不是保持模式不变(zsh 中的默认行为)。set -o globstarshort
inzsh
使**
行为像**/*
. 例如,您**/*.py
也可以写成**.py
. 在 中bash -O globstar
,**
单独类似于**/*
(除了dir/**
包含dir/
在其扩展中),但**.py
与 相同*.py
。Bash 4.0 引入了该globstar
选项和**
模式,但要注意,在 bash 4.3 之前,它总是遍历目录的符号链接,而在 5.0 之前则遍历一些符号链接。Bash 3.x 及以下版本没有这样的功能。
类似形式的递归通配符也可在tcsh
、yash
和fish
shell 中使用(默认情况下未启用)。
\xc2\xb9 请注意,当涉及到.
和..
特殊目录时,这些 shell 之间存在一些差异。它们永远不会被zsh
glob 扩展,设置FIGNORE=.:..
在 ksh93 中将它们排除,但在 bash 中它们被排除在 glob 之外,例如*
Even with dotglob
,但不从 the中排除.*
。设置GLOBIGNORE=.:..
有助于.*
,但对dir/.*
或没有帮助.*/file
。