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


24

我想通过globing在zsh中指定一个带有两个整数(例如2到57)的文件范围(按字典顺序)。

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

我认为使用方括号会做到这一点

 for x in /foo/bar/*[2-57]; do print $x; done

但岩组显然认为我要求的文件25(或类似的东西),而不是文件257。有什么想法吗?我该怎么做?

Answers:


30

[2-57]是由组成的字符集23457,在的zsh和所有其他通配符和正则表达式的语法在那里。您的glob模式*[2-57]与每个文件名的最后一个字符是这五个数字之一匹配。

我认为您忘记了[m,n] glob限定符的语法。Glob限定符始终在模式的结尾处放在括号中,而范围分隔符是逗号。模式*([2,57])扩展到第二,第三,……,第57个匹配项。默认扩展顺序为字典顺序(如果numeric_glob_sort设置了此选项,则可以使用一些特殊的魔术来按数字顺序对数字进行排序);您可以使用oOglob限定符对其进行控制(例如*(om[2,57]),匹配最近的57个文件,但不包括一个最新的文件)。

for x in /foo/bar/*([2,57]); do print $x; done

不是您想要的,而是相关的,可能对将来的读者有用:如果您想枚举2至57个文件是否存在,则可以使用range brace表达式。此功能还存在于bash和ksh中。

echo hello{2..57}

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

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57

请注意,类似的模式*<2-57>可能无法达到您的期望,因为*可能也与数字匹配。例如,file58匹配*<2-57>,以file5匹配*部分和8匹配<2-57>部分。该模式*[^0-9]<2-57>避免了此问题。


你是对的。我记错了全球预选赛。感谢您的仔细解释。
Amelio Vazquez-Reina

顺便说一句,这句话让我有点糊涂:if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression。如果文件不存在且没有匹配项,花括号扩展如何知道如何扩展?(与全球限定词有何不同?)
Amelio Vazquez-Reina

2
@intrpc foo{8..11}bar扩展为foo8bar foo9bar foo10bar foo11bar。此扩展位与文件名无关。同样,foo{eight,nine,ten,eleven}bar扩展为fooeightbar fooninebar footenbar fooelevenbar。这是ksh / bash / zsh中的大括号扩展
吉尔(Gilles)“所以,别再邪恶了”,

6

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

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

要匹配2到57之间的数字,使用序列表达式代替glob模式(或与之组合)会更容易:

for x in /foo/bar/*{2..57}; do print $x; done

编辑:但是,不幸的是,这不会给您列出的所有文件的字典顺序-由于外壳扩展,它们将按通用数字结尾分组。


谢谢@rozcietrzewiacz!我应该考虑一下。我的文件有号码他们,所以一会儿我还以为[]是印刷的东西才能..
阿梅里奥巴斯克斯-雷纳

您对的解释[2-57]是正确的,但我认为{2..57}(这是您的意思,对吗?)与intrpc想要执行的操作无关,即“按字典顺序选择2至57个文件”。
吉尔斯(Gilles)'所以

感谢您的编辑(我想该睡觉了)。而且您是对的-我忘了字典顺序部分。
rozcietrzewiacz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.