zsh中按字典顺序排列的多位文件范围

Ame*_*ina 24 zsh wildcards

我想通过通配符在 zsh 中指定具有两个整数(例如 2 到 57)的一系列文件(按字典顺序)。

例如:“在匹配某些通配模式的路径下按字典顺序选择文件 2 到 57”。

我认为使用方括号可以做到

 for x in /foo/bar/*[2-57]; do print $x; done
Run Code Online (Sandbox Code Playgroud)

但 zsh 显然认为我要求文件25(或类似的东西)而不是文件257. 任何想法为什么?我怎样才能做到这一点?

Gil*_*il' 31

[2-57]是由zsh 中的2, 3, 4,5和组成的字符集,以及7其他所有通配符和正则表达式语法。您的 glob 模式*[2-57]匹配最后一个字符是这五个数字之一的每个文件名。

我认为您记错了[m,n] glob qualifier的语法。Glob 限定符总是放在模式末尾的括号中,范围分隔符是逗号。该模式*([2,57])扩展到第 2、3、...、第 57 场比赛。默认的扩展顺序是按字典顺序排列的(如果numeric_glob_sort设置了该选项,则有一些特殊的魔法可以按数字顺序对数字进行排序);您可以使用oOglob 限定符来控制它(例如*(om[2,57])匹配 57 个最近的文件,除了一个最近的文件)。

for x in /foo/bar/*([2,57]); do print $x; done
Run Code Online (Sandbox Code Playgroud)

不是您要求的,而是相关的并且可能对未来的读者有用:如果您想枚举文件 2 到 57,无论它们是否存在,您可以使用范围大括号表达式。这个特性也存在于 bash 和 ksh 中。

echo hello{2..57}
Run Code Online (Sandbox Code Playgroud)

如果要匹配名称包含 2 到 57 之间数字的文件,可以使用模式<2-57>. 这是特定于 zsh 的。

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57
Run Code Online (Sandbox Code Playgroud)

请注意,像这样的模式*<2-57>可能不会按照您的预期进行,因为它*也可以匹配数字。例如,file58匹配*<2-57>file5匹配*部件和8匹配<2-57>部件。该模式*[^0-9]<2-57>避免了这个问题。

  • @intrpc `foo{8..11}bar` 扩展为 `foo8bar foo9bar foo10bar foo11bar`。这一点扩展与文件名无关。类似地,`foo{eight,nine,ten,eleven}bar` 扩展为 `fooeightbar fooninebar footenbar fooelevenbar`。这是 ksh/bash/zsh 中的 [支撑扩展](http://www.gnu.org/software/bash/manual/bashref.html#Brace-Expansion)。 (2认同)

roz*_*acz 6

但是 zsh 显然认为我要的是文件 2 到 5(或类似的东西)而不是文件 2 到 57。有什么想法为什么?

因为[]括号表示匹配的列表的字符(其可以是数字的),而不是数字数学解释。这种模式与单个字符匹配。该列表可以包含范围,但可以包含数字或字母。[2-57]匹配扩展为"2 到 57范围内的所有数字"

要匹配从 2 到 57 的数字,使用序列表达式而不是 globbing 模式(或与这样的模式一起使用)会更容易:

for x in /foo/bar/*{2..57}; do print $x; done
Run Code Online (Sandbox Code Playgroud)

编辑:但是,不幸的是,这不会为您提供所有列出文件的字典顺序-由于外壳扩展,它们将按常见的数字结尾进行分组。