如何在Mac OSX上模拟"sort -V"

sph*_*oid 13 git sorting macos bash gnu

我编写了一个bash脚本,我需要在linux和mac osx上以相同的方式工作,它依赖于sort命令.我正在对输出进行管道git tag -l排序,以便以正确的语义顺序获取所有版本标签的列表.GNU提供-V了这种自动化,但mac osx不支持这个参数,所以我需要弄清楚如何在没有它的情况下完成这种排序.

6.3.1.1
6.3.1.10
6.3.1.11
6.3.1.2
6.3.1.3
...
Run Code Online (Sandbox Code Playgroud)

需要排序为

6.3.1.1
6.3.1.2
6.3.1.3
...
6.3.1.10
6.3.1.11
Run Code Online (Sandbox Code Playgroud)

tbc*_*tbc 8

您可以使用 的附加功能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
Run Code Online (Sandbox Code Playgroud)

$ 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).
Run Code Online (Sandbox Code Playgroud)


Joh*_*024 3

sed 's/\b\([0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\([0-9]\)/\1/g'
Run Code Online (Sandbox Code Playgroud)

要解释其原理,请sed单独考虑第一个命令。输入为 versions.txt 后,第一个sed命令会在单位版本号上添加前导零,从而生成:

06.03.01.01
06.03.01.02
06.03.01.03
06.03.01.10
06.03.01.11
Run Code Online (Sandbox Code Playgroud)

以上可以正常排序。之后,就是删除添加的字符的问题。在完整命令中,最后一个sed命令删除前导零以产生最终输出:

6.3.1.1
6.3.1.2
6.3.1.3
6.3.1.10
6.3.1.11
Run Code Online (Sandbox Code Playgroud)

只要版本号为 99 或更低即可工作。如果版本号超过 99 但小于 1000,命令只会变得稍微复杂一些:

sed 's/\b\([0-9]\)\b/00\1/g ; s/\b\([0-9][0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\+\([0-9]\)/\1/g'
Run Code Online (Sandbox Code Playgroud)

由于我没有Mac,以上都是在Linux上测试的。

更新:在评论中,Jonathan Leffler 表示,尽管\bMac 正则表达式文档中存在单词边界 ( ),但 Macsed似乎无法识别它。他建议将第一个替换sed为:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g'
Run Code Online (Sandbox Code Playgroud)

因此,完整的命令可能是:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g' versions.txt | sort | sed 's/^0// ; s/\.0/./g' 
Run Code Online (Sandbox Code Playgroud)

这可以处理最高 99 的版本号。