我正在制定一些文件命名指南,并且正在尝试找到一种方法来允许草稿文档在最终修订之前列出。
示例:目前我的命名约定如下所示:
contract_foo_v1
contract_foo_v1~draft1
contract_foo_v1~draft2
contract_foo_v2
contract_foo_v2~draft1
问题是 v1~draft 应该列出前v1(最终修订版)。是否有一个我可以使用的字符,如下所示:
contract_foo_v1?draft1
contract_foo_v1?draft2
contract_foo_v1
contract_foo_v2?draft1
contract_foo_v2
我还了解可能存在区域设置和程序差异,因此我正在寻求在大多数情况下(或尽可能多的情况下)按要求工作的角色的建议 - 感谢您的帮助
答案1
ls
根据文件名称对文件列表进行排序,在您的情况下,文件名称不包含换行符。甚至sort
排序内容不包含换行符的行,所以这里不是要找到一个可以排序的字符换行之前,但是排序的一个在什么都没有之前而你却找不到。
现在,GNU ls -v
(用于版本排序)确实按照您想要的顺序对文件列表进行排序:
$ ls -v1
contract_foo_v1~draft1
contract_foo_v1~draft2
contract_foo_v1
contract_foo_v2~draft1
contract_foo_v2
contract_foo_v10
如果没有-v
,由于ls
进行词法排序,v10
也会在 之前排序v2
。
使用 GNU sort
,您还可以sort -V
在输出上使用ls
(假设您的文件名不包含换行符):
$ ls | sort -V
contract_foo_v1~draft1
contract_foo_v1~draft2
contract_foo_v1
contract_foo_v2~draft1
contract_foo_v2
contract_foo_v10
POSIXly,你可以这样做:
$ ls | sort -t'~' -k1.15,1n -k2,2.1r -k2n
contract_foo_v1~draft1
contract_foo_v1~draft2
contract_foo_v1
contract_foo_v2~draft1
contract_foo_v2
contract_foo_v10
但这假设版本之前的部分始终为 14 个字符长。
使用zsh
, shell,您可以定义全局排序顺序,例如:
drafts_first() {
[[ $REPLY = *'~draft'* ]] || REPLY="$REPLY~release"
}
printf '%s\n' *(no+drafts_first)
您还可以选择将文件命名为contract_foo_v001_draft01
and contract_foo_v001_release
(或contract_foo_v001_final
按照 @Kusalananda 的建议;在 之后排序的任何单词draft
),假设每个文档的版本不超过 999 个版本,每个版本的草稿数不超过 99 个,那么它们会按正确的顺序排序ls
单独或任何按词汇顺序列出文件的工具。
另请参阅ls -rt
按修改时间(最新的最后一个)或 的Om
glob 限定符对文件进行排序zsh
。
现在,如果您向这些文件名添加扩展名(例如.pdf
),那么情况就完全不同了:
$ LC_ALL=en_US.UTF-8 ls -1
contract_foo_v10.pdf
contract_foo_v1~draft1.pdf
contract_foo_v1~draft2.pdf
contract_foo_v1.pdf
contract_foo_v2~draft1.pdf
contract_foo_v2.pdf
$ LC_ALL=C ls -1
contract_foo_v1.pdf
contract_foo_v10.pdf
contract_foo_v1~draft1.pdf
contract_foo_v1~draft2.pdf
contract_foo_v2.pdf
contract_foo_v2~draft1.pdf
在我的en_US.UTF-8
语言环境中,在第一个比较过程中,~
和都被忽略,所以出现在前面,因为排序在 之前,并且出现在前面,因为排序在前面(这与扩展不同)。.
v10
v1~d
0
d
v1~draft
v1.pdf
draft
pdf
.docx
在 C 语言环境中,只有一次传递,并且排序基于字节值,.
并且0
按~
该顺序排序。~
是 ASCII 中值最高的可打印字符,因此它是最糟糕的选择。前面有很多,.
比如#
,,,全部-
%
被忽略在上面的第一遍中,在遵循 iso14651_t1 的语言环境中。
因此,如果我们使用 0 填充来修复 v2 与 v10 的问题,并使用 ,-
代替, 以及扩展~
,.pdf
我们就会得到我们想要的顺序人类区域设置和 in C
/C.UTF-8
区域设置,其中顺序基于代码点:
$ LC_ALL=en_US.UTF-8 ls -1
contract_foo_v01-draft1.pdf
contract_foo_v01-draft2.pdf
contract_foo_v01.pdf
contract_foo_v02-draft1.pdf
contract_foo_v02.pdf
contract_foo_v10.pdf
$ LC_ALL=C ls -1
contract_foo_v01-draft1.pdf
contract_foo_v01-draft2.pdf
contract_foo_v01.pdf
contract_foo_v02-draft1.pdf
contract_foo_v02.pdf
contract_foo_v10.pdf