Hello StackExchange社区!
我正在尝试解决使用批处理对浮点值进行排序的问题。
重点。我有一个日志文件(INPUT.txt),格式如下:
889.W_1.153,46
889.W_1.37,43
889.W_1.28,81
889.W_1.34,70
155.W_2.22,67
155.W_2.108,06
155.W_2.22,11
155 W_2 22,65
我想按第1和第3列排序。我希望以这种形式输出(OUTPUT.txt):
155.W_2.22,11
155.W_2.22,65
155.W_2.22,67
155.W_2.108,06
889.W_1.28,81
889.W_1.34,70
889.W_1.37,43
889.W_1.153,46
我写了一个小脚本,它的效果差不多因为我的结果是:
155 108,06 W_2
155 22,11 W_2
155 22,65 W_2
155 22,67 W_2
889 153,46 W_1
889 28,81 W_1
889 34,70 W_1
889 37,43 W_1
点和列顺序不是那么重要,实际问题是数字长于2位数。逗号被视为比数字“更高”。以下是剧本:
@echo off
setlocal enabledelayedexpansion
for /F "tokens=1-3 delims=." %%a in (INPUT.txt) do set "a[%%a %%c ]=%%b"
for /F "tokens=2-4 delims=[.]=" %%a in ('set a[') do echo %%a%%c%%b>> OUTPUT.txt
正确的分类不是我需要的一切。我也有能力(稍后在脚本中)删除数字长度超过2位的整行,在这种情况下,它将是153,49
和108,06
的行。任何帮助对我都很有价值。
答案 0 :(得分:1)
纯批处理程序不支持数字排序,需要解决。最好的方法是用零填充数字,然后进行原生字母排序。
要进行实际排序,您可以像在脚本中一样使用set
。这是一个批处理文件,其中包含所述零填充:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "FILE=%~1" & rem // (1st command line argument: file to process)
set "RTNF=%~2" & rem // (2nd command line argument: file to store result)
set /A DIGS=4 & rem // (total number of digits for zero-padding)
set /A DLIM=2 & rem // (maximum number of digits for 3rd field in file)
if not defined RTNF set "RTNF=con"
for /F "eol== delims==" %%V in ('2^> nul set ARRAY[') do set "%%V="
setlocal EnableDelayedExpansion
set "PAD=" & for /L %%D in (1,1,%DIGS%) do set "PAD=!PAD!0"
endlocal & set "PAD=%PAD%"
setlocal EnableDelayedExpansion
for /F usebackq^ delims^=^ eol^= %%L in ("!FILE!") do (
endlocal
for /F "eol=. tokens=1,3,4 delims=., " %%A in ("%%L") do (
set "FIELD1=%PAD%%%A"
set "FIELD3=%%B"
set "FIELD4=%%C%PAD%"
setlocal EnableDelayedExpansion
if "!FIELD3:~%DLIM%!"=="" (
set "FIELD3=%PAD%!FIELD3!"
for /F delims^=^ eol^= %%T in ("!FIELD1:~-%DIGS%!.!FIELD3:~-%DIGS%!,!FIELD4:~,4!") do (
endlocal
set "ARRAY[%%T]=%%L"
)
) else (
endlocal
)
)
setlocal EnableDelayedExpansion
)
> "!RTNF!" (
for /F "tokens=2 delims== eol==" %%I in ('set ARRAY[') do (
endlocal
echo(%%I
setlocal EnableDelayedExpansion
)
)
endlocal
endlocal
exit /B
对于排序,使用伪数组变量ARRAY
,其索引包含用于排序的适用字段的零填充数,值是输入文件的原始行:
ARRAY[0155.0022,1100]=155.W_2.22,11 ARRAY[0155.0022,6500]=155 W_2 22,65 ARRAY[0155.0022,6700]=155.W_2.22,67 ARRAY[0889.0028,8100]=889.W_1.28,81 ARRAY[0889.0034,7000]=889.W_1.34,70 ARRAY[0889.0037,4300]=889.W_1.37,43
这是另一种使用临时文件和sort
命令进行排序的方法。这更通用,因为它不会对特殊字符(例如=
)失败,这会对基于set
命令的方法产生负面影响。这是代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "FILE=%~1" & rem // (1st command line argument: file to process)
set "RTNF=%~2" & rem // (2nd command line argument: file to store result)
set /A DIGS=4 & rem // (total number of digits for zero-padding)
set /A DLIM=2 & rem // (maximum number of digits for 3rd field in file)
set "TMPF=%TEMP%\%~n0_%RANDOM%.tmp"
if not defined RTNF set "RTNF=con"
setlocal EnableDelayedExpansion
set "PAD=" & for /L %%D in (1,1,%DIGS%) do set "PAD=!PAD!0"
endlocal & set "PAD=%PAD%"
setlocal EnableDelayedExpansion
> "!TMPF!" (
for /F usebackq^ delims^=^ eol^= %%L in ("!FILE!") do (
endlocal
set "LINE=%%L"
for /F "eol=. tokens=1,3,4 delims=., " %%A in ("%%L") do (
set "FIELD1=%PAD%%%A"
set "FIELD3=%%B"
set "FIELD4=%%C%PAD%"
setlocal EnableDelayedExpansion
if "!FIELD3:~%DLIM%!"=="" (
set "FIELD3=%PAD%!FIELD3!"
echo(!FIELD1:~-%DIGS%!.!FIELD3:~-%DIGS%!,!FIELD4:~,4!^|!LINE!
)
endlocal
)
setlocal EnableDelayedExpansion
)
)
> "!RTNF!" (
for /F delims^=^ eol^= %%I in ('sort "!TMPF!"') do (
endlocal
set "LINE=%%I"
setlocal EnableDelayedExpansion
echo(!LINE:*^|=!
)
)
del "!TMPF!"
endlocal
endlocal
exit /B
用于排序的临时文件包含用于排序的适用字段的零填充数字,预定义的分隔符|
以及输入文件的原始行:
0889.0037,4300|889.W_1.37,43 0889.0028,8100|889.W_1.28,81 0889.0034,7000|889.W_1.34,70 0155.0022,6700|155.W_2.22,67 0155.0022,1100|155.W_2.22,11 0155.0022,6500|155 W_2 22,65
答案 1 :(得分:0)
您的代码只需要进行一些小调整:
@echo off
setlocal EnableDelayedExpansion
for /F "tokens=1-4 delims=.," %%a in (INPUT.txt) do (
set /A "first=1000+%%a,third=100000+%%c%%d"
set "a[!first!!third!]=%%a.%%b.%%c,%%d"
)
(for /F "tokens=2 delims==" %%a in ('set a[') do echo %%a) > OUTPUT.txt