2016-05-13 2 views
1

Hallo StackExchange-Community!Gleitkommazahlen im Stapel sortieren

Ich versuche, das Problem des Sortierens Gleitkommawerte mit Charge zu lösen.

Auf den Punkt. Ich habe eine Protokolldatei (input.txt) in der folgenden Form:

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 

Ich möchte dies sortieren von 1. und 3. Spalte. Ich möchte Ausgang (output.txt) in dieser Form:

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 

ich ein kleines Skript geschrieben und es funktioniert fast gut, weil mein Ergebnis ist:

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 

Punkte und Spaltenreihenfolge sind nicht so wichtig, tatsächliches Problem ist mit Zahlen länger als 2 Ziffern. Ein Komma wird als "höher" als die Zahl behandelt. Unten ist das Skript:

@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 

korrekte Sortierung ist nicht alles was ich brauche. Ich hätte auch die Möglichkeit (später im Skript), eine ganze Zeile zu löschen, in der die Nummer länger als 2 Ziffern ist, in diesem Fall wird es Zeile mit 153,49 und 108,06 sein. Jede Hilfe wäre sehr wertvoll für mich.

+0

In der letzten Zeile Ihres 'INPUT.txt' Datensamples gibt es keine Punkte' .' ('155 W_2 22,65'); Ich nehme an, das ist ein Tippfehler, oder? – aschipfl

Antwort

1

Numerische Sortierung wird nicht durch reine Batch-Programme unterstützt und müssen um gearbeitet werden. Die beste Methode besteht darin, Zahlen mit Nullen zu füllen und dann eine alphabetische Sortierung durchzuführen.

tatsächlich sortieren, können Sie set verwenden, wie Sie bereits in Ihrem Skript tat. Hier ist eine Batchdatei, die die genannten Zero-Padding Merkmale:

@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 

zum Sortieren, ein pseudo-Arrayvariable ARRAY verwendet wird, deren Indizes enthalten, die mit Nullen aufgefüllt Nummern der entsprechenden Felder für die Sortierung, die Werte sind die ursprünglichen Zeilen der Eingabedatei:

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 

Hier ist ein weiterer Ansatz, eine temporäre Datei und die sort mit com zu sortieren. Dies ist generischer, da es bei Sonderzeichen, wie zum Beispiel , nicht fehlschlägt, was die Methode, die auf dem set-Befehl basiert, nachteilig beeinflusst. Dies ist der Code:

@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 

Die temporäre Datei zur Sortierung verwendet wird, enthält die Nullen aufgefüllten Nummern der entsprechenden Felder zum Sortieren, ein vordefiniertes Trennzeichen | und die ursprünglichen Zeilen der Eingabedatei:

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

Das war der Code, den ich befürchtet hatte, war notwendig ;-) Schön gemacht (auch das ist ein böser Trick, 'Set' zum Sortieren zu missbrauchen: D). – Joey

0

Ihr Code benötigt nur eine kleine Anpassung:

@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