我写了一个bash脚本,我需要在依赖于sort
命令的linux和macOS上以相同的方式工作。我正在将git tag -l
的输出管道传输到sort
,以正确的语义顺序获取所有版本标签的列表。GNU 提供了-V
这使得这个自动魔术,但 macOS 不支持这个论点,所以我需要弄清楚如何在没有它的情况下完成这种排序顺序。
6.3.1.1
6.3.1.10
6.3.1.11
6.3.1.2
6.3.1.3
...
需要排序为
6.3.1.1
6.3.1.2
6.3.1.3
...
6.3.1.10
6.3.1.11
您可以使用git tag
的其他功能来获取与模式匹配的标签列表,并按版本标签排序正确排序(通常没有前导零):
$ git tag --sort v:refname
v0.0.0
v0.0.1
v0.0.2
v0.0.3
v0.0.4
v0.0.5
v0.0.6
v0.0.7
v0.0.8
v0.0.9
v0.0.10
v0.0.11
v0.0.12
从$ man git-tag
:
--sort=<type>
Sort in a specific order. Supported type is "refname
(lexicographic order), "version:refname" or "v:refname"
(tag names are treated as versions). Prepend "-" to reverse
sort order. When this option is not given, the sort order
defaults to the value configured for the tag.sort variable
if it exists, or lexicographic order otherwise. See
git config(1).
brew install coreutils
如果安装了 corutils,您应该在 Mac 上安装 gsort
gsort --version
您可以从 http://rudix.org/packages/index.html 下载coreUtils
它包含gnusort
与支持sort -V
sintax
sed 's/b([0-9])b/01/g' versions.txt | sort | sed 's/b0([0-9])/1/g'
为了解释为什么这样做,请考虑第一个sed
命令本身。 将输入作为版本.txt,第一个sed
命令在个位数版本号上添加一个前导零,从而产生:
06.03.01.01
06.03.01.02
06.03.01.03
06.03.01.10
06.03.01.11
以上可以正常排序。 之后,是删除添加的字符的问题。 在完整命令中,最后一个sed
命令删除前导零以生成最终输出:
6.3.1.1
6.3.1.2
6.3.1.3
6.3.1.10
6.3.1.11
只要版本号为 99 或更少,就可以工作。 如果您的版本号超过 99 但小于 1000,则该命令只会稍微复杂一些:
sed 's/b([0-9])b/001/g ; s/b([0-9][0-9])b/01/g' versions.txt | sort | sed 's/b0+([0-9])/1/g'
由于我没有Mac,因此在Linux上进行了测试。
更新:在评论中,Jonathan Leffler说,即使单词边界(b
)在Mac正则表达式文档中,Macsed
似乎也无法识别它。 他建议将第一个sed
替换为:
sed 's/^[0-9]./0&/; s/.([0-9])$/.01/; s/.([0-9])./.01./g; s/.([0-9])./.01./g'
因此,完整的命令可能是:
sed 's/^[0-9]./0&/; s/.([0-9])$/.01/; s/.([0-9])./.01./g; s/.([0-9])./.01./g' versions.txt | sort | sed 's/^0// ; s/.0/./g'
这将处理最多 99 的版本号。
OS X 上安装的标准排序可以使用分隔符按字段排序。 因此,您可以对版本号和任何后缀进行排序。
这将首先按后缀排序,然后按 X.Y.Z 部件sort -s -t- -k 2,2n | sort -t. -s -k 1,1n -k 2,2n -k 3,3n -k 4,4n
排序,这也可以从git describe --tags
命令对 -N-g 格式的版本号进行排序
0.11.1
0.11.4
0.11.9-1-ge6b0c59
0.12.0
0.12.1
0.12.2-1-g2d0a334
0.13.0
0.13.0-1-g7711b16
0.13.0-2-g32f91bd
0.13.0-3-g83e21c5
0.14.1-alpha
0.14.1
0.14.2
上面的 -3-g83e21c5 是一个后缀示例,git describe --tags
命令将自动附加到最新标记,以表示自标记 (3) 以来的提交数,以及最近提交的 Git SHA 哈希 (83e21c5)
要将排序反转为降序,请执行以下操作:sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
或者,您可以围绕它定义一个 shell 函数。
version_sort() {
# read stdin, sort by version number descending, and write stdout
# assumes X.Y.Z version numbers
# this will sort tags like pr-3001, pr-3002 to the END of the list
# and tags like 2.1.4 BEFORE 2.1.4-gitsha
sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
}
或者把它写到一个名为version-sort的小文件中,然后放到PATH上的某个目录中。 请务必chmod +x
文件上
#!/usr/bin/env bash
sort -s -t- -k 2,2nr | sort -t. -s -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr