在纯批处理脚本中,您可以使用以下代码 sn-p:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
> "versions.tmp" (
for /F "usebackq tokens=1,2,3,4 delims=." %%I in ("versions.txt") do (
set "ITEM1=000%%I" & set "ITEM2=000%%J" & set "ITEM3=000%%K" & set "ITEM4=000%%L"
echo !ITEM1:~-4!.!ITEM2:~-4!.!ITEM3:~-4!.!ITEM4:~-4!^|%%I.%%J.%%K.%%L
)
)
< "versions.tmp" (
for /F "tokens=2 delims=|" %%S in ('sort') do (
echo %%S
)
)
del /Q "versions.tmp"
endlocal
exit /B
这将创建一个临时文件,其中包含原始行,前缀为填充的版本号和分隔符|。填充数字意味着每个组件都用前导零填充到四位数字。以下是基于您的样本数据的示例:
0003.0006.0004.0002|3.6.4.2
0003.0006.0005.0001|3.6.5.1
0003.0006.0005.0010|3.6.5.10
0003.0006.0005.0011|3.6.5.11
0003.0006.0005.0012|3.6.5.12
0003.0006.0005.0013|3.6.5.13
0003.0006.0005.0002|3.6.5.2
0003.0006.0007.0001|3.6.7.1
0003.0006.0007.0010|3.6.7.10
0003.0006.0007.0011|3.6.7.11
0003.0006.0007.0002|3.6.7.2
0003.0006.0007.0003|3.6.7.3
这个临时文件然后被传递给sort,它进行纯粹的字母排序。由于数字被填充,排序顺序等于真正的字母数字顺序。以下是使用上述示例的排序结果:
0003.0006.0004.0002|3.6.4.2
0003.0006.0005.0001|3.6.5.1
0003.0006.0005.0002|3.6.5.2
0003.0006.0005.0010|3.6.5.10
0003.0006.0005.0011|3.6.5.11
0003.0006.0005.0012|3.6.5.12
0003.0006.0005.0013|3.6.5.13
0003.0006.0007.0001|3.6.7.1
0003.0006.0007.0002|3.6.7.2
0003.0006.0007.0003|3.6.7.3
0003.0006.0007.0010|3.6.7.10
0003.0006.0007.0011|3.6.7.11
最后,如果您只想返回最新版本号,echo %%S by set "LVER=%%S" 并将echo !LVER! 放在第二个for /F 循环的关闭) 之后。
更新:
这是一个不产生任何临时文件的解决方案,而是使用管道|。由于管道为左侧和右侧创建了新的cmd 实例,并且由于(控制台)输出以微小位构建并且完成了多个算术运算,所以它相当慢:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
(
for /F "usebackq tokens=1,2,3,4 delims=." %%I in ("versions.txt") do @(
set /A "10000+%%I" & echo( ^| set /P "=."
set /A "10000+%%J" & echo( ^| set /P "=."
set /A "10000+%%K" & echo( ^| set /P "=."
set /A "10000+%%L" & echo(
)
) | (
for /F "tokens=1,2,3,4 delims=." %%S in ('sort') do @(
set /A "%%S-10000" & echo( ^| set /P "=."
set /A "%%T-10000" & echo( ^| set /P "=."
set /A "%%U-10000" & echo( ^| set /P "=."
set /A "%%V-10000" & echo(
)
)
endlocal
exit /B
管道左侧:
为了避免delayed expansion,我将10000添加到版本号的每个组件(类似于Aacini's answer)中,而不是像上面使用临时文件的方法中的子字符串扩展语法,因为这不是在任一新的 cmd 实例中启用。为了输出结果值,我利用for /F 循环在cmd 上下文而不是batch 上下文中运行的事实,其中set /A 将结果输出到STDOUT。 set /A 不会用换行符终止它的输出,所以我使用set /P 在每个但最后一个项目之后附加一个.,这反过来又不附加换行符。对于最后一项,我使用空白 echo 附加一个换行符。
管道右侧:
排序再次由sort 命令完成,其输出由for /F 解析。这里从每个组件中减去先前添加的值10000 以检索原始数字。为了将结果输出到控制台,使用与管道另一侧相同的技术。
管道数据:
管道传递过来的数据是这样的(再次依赖问题的例子):
10003.10006.10004.10002
10003.10006.10005.10001
10003.10006.10005.10010
10003.10006.10005.10011
10003.10006.10005.10012
10003.10006.10005.10013
10003.10006.10005.10002
10003.10006.10007.10001
10003.10006.10007.10010
10003.10006.10007.10011
10003.10006.10007.10002
10003.10006.10007.10003