我想通过通配符在 zsh 中指定具有两个整数(例如 2 到 57)的一系列文件(按字典顺序)。
例如:“在匹配某些通配模式的路径下按字典顺序选择文件 2 到 57”。
我认为使用方括号可以做到
for x in /foo/bar/*[2-57]; do print $x; done
Run Code Online (Sandbox Code Playgroud)
但 zsh 显然认为我要求文件2
到5
(或类似的东西)而不是文件2
到57
. 任何想法为什么?我怎样才能做到这一点?
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
设置了该选项,则有一些特殊的魔法可以按数字顺序对数字进行排序);您可以使用o
或O
glob 限定符来控制它(例如*(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>
避免了这个问题。
但是 zsh 显然认为我要的是文件 2 到 5(或类似的东西)而不是文件 2 到 57。有什么想法为什么?
因为[]
括号表示匹配的列表的字符(其可以是数字的),而不是数字数学解释。这种模式与单个字符匹配。该列表可以包含范围,但可以包含数字或字母。[2-57]
匹配扩展为"2 到 5和7范围内的所有数字"。
要匹配从 2 到 57 的数字,使用序列表达式而不是 globbing 模式(或与这样的模式一起使用)会更容易:
for x in /foo/bar/*{2..57}; do print $x; done
Run Code Online (Sandbox Code Playgroud)
编辑:但是,不幸的是,这不会为您提供所有列出文件的字典顺序-由于外壳扩展,它们将按常见的数字结尾进行分组。