可以在 zsh 中结合 glob 排序和交替吗?

Possible to combine glob sort w/ alternation in zsh?

正在寻找一种 shell-only[1] 方法来获取此目录列表:

foo1.1
foo1.10
foo1.10/bar
foo1.2
foo1.3
foo1.3/bar
foo1.4
foo1.5
foo1.5/bar
foo1.6
foo1.7
foo1.8
foo1.9
foo2.1

并且 return 它按数字排序,子目录显示在其父目录之后:

foo1.1
foo1.2
foo1.3
foo1.3/bar
foo1.4
foo1.5
foo1.5/bar
foo1.6
foo1.7
foo1.8
foo1.9
foo1.10
foo1.10/bar
foo2.1

(*|*/bar)(n) 作为错误模式被拒绝,而 */{,bar}(n) 扩展为 */(n) ~/bar(n) 因此子目录显示在末尾。

[1] 我需要它能够在各种系统上工作,所以使用 GNU sort 的 -V 或 GNU ls 的 -v 或类似的方法将不起作用。

您可以通过两个步骤轻松完成:列表,然后排序。

dirs=(* */bar)
dirs=(${(on)dirs})

这依赖于 / 在现有目录的任何后缀之前排序,因此如果您的目录名称类似于 foo1.3-qux(它将在 [=15 之间排序) =] 和 foo1.3/bar。因为所有的文件都是目录,你可以用一个临时的 / 后缀解决这个问题,如果 foo1.3-quxfoo1.3 之前排序是可以的:

dirs=(*/ */bar)
dirs=(${${(on)dirs}%/})

为了更稳健,您可以暂时用空字节替换 / 字符,这样可以保证先于任何其他字符排序(至少在 C 语言环境中)并且不会出现在文件名中.

dirs=(* */bar)
dirs=(${${(on)${dirs//\//$'[=12=]'}}//$'[=12=]'//})