我在 Linux 下运行 zsh setopt extended_glob ksh_glob glob_dots
。我正在寻找易于在命令行上键入的内容,并且没有可移植性要求。我正在查看源代码树,没有“奇怪”的文件名(例如,没有\
文件名,没有以 开头的文件名-
)。
以下任一命令都会递归打印当前目录的子目录列表:
find -type d
print -l **/*/
这实际上是一个 svn checkout:
$ find -type d
./.deps
./.svn
./.svn/text-base
./.svn/prop-base
./.svn/tmp
./.svn/tmp/text-base
./.svn/tmp/prop-base
./.svn/tmp/props
./.svn/props
./lib/.svn
./lib/.svn/text-base
./lib/.svn/prop-base
./lib/.svn/tmp
./lib/.svn/tmp/text-base
./lib/.svn/tmp/prop-base
./lib/.svn/tmp/props
./src/.svn
./src/.svn/text-base
./src/.svn/prop-base
./src/.svn/tmp
./src/.svn/tmp/text-base
./src/.svn/tmp/prop-base
./src/.svn/tmp/props
我想排除.svn
每个目录中存在的目录及其子目录。这很容易find
:
find -type d -name .svn -prune -o -print
我可以用一个短的 zsh glob 来做到这一点吗?忽略点文件很接近(我需要明确地执行它,因为我已经glob_dots
设置了):
print -l **/*(/^D)
但这并不令人满意,因为它隐藏了.deps
我确实想查看的目录。我可以过滤掉包含以下内容的路径.svn
:
print -l **/*~(*/|).svn(|/*)(/)
find
但这仅比(那么我使用 zsh 做什么?)短一点。我可以将其缩短为print -l **/*~*.svn*(/)
,但这也会过滤掉名为 的目录hello.svn
。此外,zsh 遍历.svn
目录,这在 NFS 或 Cygwin 上有点慢。
是否有一种方便的(如易于键入)方法来排除递归全局中的特定目录名称(甚至更好:任意模式)?
答案1
Zsh 的扩展 glob 运算符支持匹配/
(与 ksh 不同,即使在 zsh 的实现中也是如此)。 Zsh是(重复 0 次或多次)**/
的快捷方式。所以我需要做的就是将其替换为(除 之外的任何内容)。(*/)#
*/
*
^.svn
.svn
print -l (^.svn/)#
整洁的!
答案2
虽然通配符即使使用选项也ksh93
远不及 ,但可以通过以下方式实现:zsh
globstar
ksh93
set -o globstar
FIGNORE='@(.|..|.svn)'
printf '%s\n' **/