2016-05-13 59 views
1

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 

我想在第一和第三列進行排序這一點。我想輸出(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,49108,06。任何幫助對我來說都是非常有價值的。

+0

在你的'INPUT.txt'數據樣本的最後一行,沒有點'。'('155 W_2 22,65');我認爲這是一個錯字,對吧? – aschipfl

回答

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 COM的另一種方法必須進行分類。這更通用,因爲它不會在特殊字符上失敗,例如=,這會對基於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 
+0

這就是我擔心的代碼是必要的;-)很好地完成(這也是濫用'set'進行排序的惡作劇:D)。 – Joey

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