大家好,我在cmd中对SORT命令感到困惑 我试图对包含这些值的speed.txt文本文件进行排序
> time=1ms
time=3ms
time=267ms
time=4ms
time=167ms
我使用命令sort /r speed.txt > sorted.txt
来输出我期望包含的sorted.txt
> time=267ms
time=167ms
time=4ms
time=3ms
time=1ms
但输出是
> time=4ms
time=3ms
time=267ms
time=167ms
time=1ms
任何人都可以帮助我获得所需的输出吗?我是cmd命令的新手,我仍处于基本命令
答案 0 :(得分:1)
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
for /f "tokens=3 delims=m=^>" %%A in (speed.txt
) do Set /A "time=10000+%%A"&set "T[!time!]=x"
For /f "tokens=2delims=[]" %%A in ('Set T['
) Do Set /A "time=%%A-10000"&Echo time=!time!ms
使用您的确切上述输入数据的示例输出(假设文件speed.txt):
time=1ms
time=3ms
time=4ms
time=167ms
time=267ms
批处理解析输入,在等号和>
处分割字母m处的行(以除去ms)。成功的令牌被计为一个,因此可以选择令牌3。要对数字进行排序(字面意思),它们必须具有相同的长度,我通过向每个数字添加10000并将它们存储在数组中来实现。
/ f的第二个用于调用数组,减去先前添加的偏移量10000并以time=#ms
编辑将文件更改为speed.txt
答案 1 :(得分:0)
这是一种可以处理最多八位数甚至重复数字值的方法;它依赖于set
命令的排序功能:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~1"
rem /* Store all lines into an array-style variable set `ARRAY[]` with
rem the left-zero-padded time value as the first index, the current
rem line number as the second index to avoid loss of duplicate values
rem and the current line string are the value: */
for /F "tokens=1* delims== eol==" %%K in ('findstr /N "^" "%_FILE%"') do (
set "KEY=%%K" & set "VAL=%%L"
setlocal EnableDelayedExpansion
set /A "NUM=100000000+VAL, LIN=100000000+KEY"
set "KEY=!KEY:*:=!"
for /F "delims=" %%E in ("ARRAY[!NUM:~1!_!LIN:~1!]=!KEY!=!VAL!") do (
endlocal
set "%%E"
)
)
rem // Return values of the array elements sorted by their index:
for /F "tokens=1* delims==" %%K in ('2^> nul set ARRAY[') do (
echo(%%L
)
endlocal
exit /B
以下是使用sort
命令和管道|
的替代方法:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~1"
rem /* Precede every line with the sum of `900000000` and the time value,
rem so the resulting number always consists of nine digits, given that
rem the value is less than `100000000`; the prefix is separated from
rem the original text file string by a `|` character; the resulting
rem text is fed into another block of code via a pipe `|`; since pipes
rem instantiate new `cmd` instances for either side, and each side is
rem executed under `cmd` context, the `set /A` command, in contrast to
rem batch file context, returns the (last) result without a trailing
rem line-break, so the text of the next `echo` command is appended;
rem the augmented lines are fed into the `sort` command via a pipe `|`,
rem the prefix is split off using the `|` character (which the original
rem line text must not begin with); `sort` does pure string sorting,
rem but since the number of digits of the prefix is always the same,
rem the alphabetic (string) order equals the numeric order; finally;
rem the prefix is removed from the rest, which is the original text: */
(
rem/ // Read the text file line by line, disregard empty lines:
for /F "usebackq tokens=1* delims== eol==" %%K in ("%_FILE%") do @(
rem/ // Extract the numeric part, add "900000000", return result:
set "VAL=%%L" & set /A "900000000+VAL"
rem/ // Append "|", followed by the original line string:
echo(^^^|%%K=%%L
)
) | (
rem/ /* Feed augmented text into "sort", read output line by line,
rem/ split off "|" and everything in front: */
for /F "tokens=1* delims=|" %%K in ('sort') do @(
rem/ // Return original line string:
echo(%%L
)
)
endlocal
exit /B