在 coreutils 的手册中,
10.1.4 版本排序详情,
版本排序处理文件名经常包含的事实 索引或版本号。标准排序通常不会产生人们期望的顺序,因为比较是逐个字符进行的。当浏览包含许多名称中带有索引/版本号的文件的目录时,版本排序特别有用:
$ ls -1 $ ls -1v abc.zml-1.gz abc.zml-1.gz abc.zml-12.gz abc.zml-2.gz abc.zml-2.gz abc.zml-12.gz
比较按版本排序的字符串, 以便 if
ver1
和ver2
版本号和字首和后缀(与正则表达式匹配的后缀‘(\.[A-Za-z~][A-Za-z0-9~]*)*’
)是字符串,那么ver1
<ver2
暗示该名称由prefix ver1 suffix
之前的排序 组成prefix ver2 suffix
。另请注意,数字部分的前导零将被忽略:
$ ls -1 $ ls -1v abc-1.007.tgz abc-1.01a.tgz abc-1.012b.tgz abc-1.007.tgz abc-1.01a.tgz abc-1.012b.tgz
此功能是使用 gnulib 的
filevercmp
函数实现的,该函数有一些值得注意的注意事项。•
LC_COLLATE
被忽略,这意味着ls -v
将对sort -V
非数字进行排序前缀就好像LC_COLLATE
区域设置类别设置为C
.• 一些后缀不会被上面提到的正则表达式匹配。因此,这些示例可能不会按您的预期排序:
abc-1.2.3.4.7z abc-1.2.3.7z abc-1.2.3.4.x86_64.rpm abc-1.2.3.x86_64.rpm
- 给定一个文件名,前缀、版本号和后缀的定义是什么?
对于后缀,在正则表达式 中
‘(\.[A-Za-z~][A-Za-z0-9~]*)*’
,- 这是什么
~
意思? - 是
‘
正则表达式的一部分吗?
是否在某处引入了正则表达式的语法?
- 这是什么
在这三个示例中,文件名的前缀、版本号和后缀是什么?
在最后一个示例中,即最后一个警告中的示例,为什么文件名按版本排序方式排序?
谢谢。
答案1
当然,这很难解释。
只有阅读源码才能达到终极熏陶:https://github.com/gagern/gnulib/blob/master/lib/filevercmp.c。基本上:
后缀是匹配的最长字符串(\.[A-Za-z~][A-Za-z0-9~]*)*$
。请注意,$
这要求匹配位于文件名的末尾。后缀的点分隔部分被视为版本号以进行比较。
这~
只是一个可能出现在文件名中的字符。这有时用在版本号中,例如3.4.1~alpha
.
在最后一个示例中,即最后一个警告中的示例,为什么文件名按版本排序方式排序?
由于_
不是允许的后缀字符,因此以 结尾的文件x86_64.rpm
将被视为无版本(或仅rpm
被视为版本)。目前尚不清楚为什么它们不按字典顺序排序作为后备。