Antworten:
Die allgemeine numerische Sortierung vergleicht die Zahlen als Gleitkommazahlen. Dies ermöglicht eine wissenschaftliche Notation, z. B. 1.234E10, ist jedoch langsamer und unterliegt einem Rundungsfehler (1.2345678 könnte nach 1.2345679 kommen). Die numerische Sortierung ist nur eine reguläre alphabetische Sortierung, bei der 10 nach 9 steht.
Siehe http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
'-g' '--general-numeric-sort' '--sort = general-numeric' Mit der Standard-C-Funktion strtod numerisch sortieren, um ein Präfix jeder Zeile in eine Gleitkommazahl mit doppelter Genauigkeit umzuwandeln. Dies ermöglicht die Angabe von Gleitkommazahlen in wissenschaftlicher Notation wie 1.0e-34 und 10e100. Das Gebietsschema LC_NUMERIC bestimmt das Dezimalzeichen. Melden Sie keine Überlauf-, Unterlauf- oder Konvertierungsfehler. Verwenden Sie die folgende Sortierfolge: Zeilen, die nicht mit Zahlen beginnen (alle werden als gleich angesehen). NaNs ("Not a Number" -Werte in IEEE-Gleitkomma-Arithmetik) in einer konsistenten, aber maschinenabhängigen Reihenfolge. Minus unendlich. Endliche Zahlen in aufsteigender numerischer Reihenfolge (mit -0 und +0 gleich). Plus unendlich.
Verwenden Sie diese Option nur, wenn es keine Alternative gibt. Es ist viel langsamer als --numeric-sort (-n) und kann beim Konvertieren in Gleitkommazahlen Informationen verlieren.
'-n' '--numeric-sort' '--sort = numeric' Numerisch sortieren. Die Zahl beginnt in jeder Zeile und besteht aus optionalen Leerzeichen, einem optionalen '-' - Zeichen und null oder mehr Ziffern, die möglicherweise durch Tausende Trennzeichen getrennt sind, optional gefolgt von einem Dezimalzeichen und null oder mehr Ziffern. Eine leere Zahl wird als '0' behandelt. Das Gebietsschema LC_NUMERIC gibt das Dezimalzeichen und das Tausendertrennzeichen an. Standardmäßig ist ein Leerzeichen ein Leerzeichen oder eine Registerkarte, das Gebietsschema LC_CTYPE kann dies jedoch ändern.
Der Vergleich ist genau; Es liegt kein Rundungsfehler vor.
Weder ein führendes '+' noch eine exponentielle Notation werden erkannt. Verwenden Sie die Option --general-numeric-sort (-g), um solche Zeichenfolgen numerisch zu vergleichen.
-k3.2n
oder -k3.2g
wird R10
vorher sortiert R2
. Die Sortierung ist lexikografisch und nicht numerisch. Ich erwarte, dass das Feld ab dem zweiten Zeichen als Zahl behandelt wird.
sort
's Schlüsselspezifikationen. sind wirklich byzantinisch - das kurze daran ist: Die Leerzeichen vor dem Feld werden als Teil des Feldes betrachtet , also char. Index 1 zeigt auf das (erste) Leerzeichen vor dem Feld, nicht auf das tatsächliche erste Zeichen des Feldes. Suffix das Zeichen. Index mit b
, um dieses Problem zu beheben, dh: -k 3.2bn,3
(Beachten Sie, dass die globale -b
Option in diesem Fall nicht funktioniert). Beachten Sie auch das hinzugefügte ,3
, das sicherstellt, dass nur das 3. Feld verwendet wird - ohne diesen 2. Feldindex wird der Rest der gesamten Zeile verwendet.
Sie sollten mit Ihrem Gebietsschema vorsichtig sein. Beispielsweise möchten Sie möglicherweise eine gleitende Zahl (wie 2.2) sortieren, während Ihr Gebietsschema möglicherweise die Verwendung eines Kommas (wie 2,2) erwartet.
Wie in diesem Forum berichtet , können Sie mit den Flags -n oder -g falsche Ergebnisse erzielen.
In meinem Fall benutze ich:
LC_ALL=C sort -k 6,6n file
um die 6. Spalte zu sortieren, die enthält:
2.5
3.7
1.4
um zu erhalten
1.4
2.5
3.7
-n
Komma nicht als Tausendertrennzeichen erkennen - "1.000" wird genauso behandelt wie "1".
sort
Verwendet die Logik mit dem längsten Präfix : Der längste Teil der Zeile / des Schlüssels, den er als Zahl erkennt, wird verwendet. In einem Gebietsschema, das .
als Radix-Zeichen verwendet wird, hört das Lesen bei auf ,
.
LC_ALL=C
ist in der Tat die robusteste Wahl; Wenn jedoch LC_ALL
nicht gesetzt LANG=C
wird, funktioniert dies auch.
LANG=C sort -k 6,6n file
sowohl einfacher als auch lokalisiert den Effekt des Festlegens von Umgebungsvariablen LANG
auf den spezifischen Befehl.
Zusätzlich zu der akzeptierten Antwort, die -g
eine wissenschaftliche Notation zulässt , möchte ich den Teil zeigen, der höchstwahrscheinlich unerwünschtes Verhalten verursacht.
Mit -g
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -g myfile
baa
--inf
--inf
--inf-
--inf--
--inf-a
--nnf
nnf--
nnn
tnan
zoo
naN
Nana
nani lol
-inf
-inf--
-11
-2
-1
1
+1
2
+2
0xa
11
+11
inf
Schauen Sie sich die zoo
drei wichtigen Dinge hier an:
Die Linie beginnt mit NAN
(zB Nana
und nani lol
) oder -INF
(einzelner Bindestrich, nicht--INF
) bis zum Ende, jedoch vor den Ziffern. Während INF
Umzug in den letzten nach Ziffern , weil es bedeutet, unendlich .
Die NAN
,INF
und -INF
sind Groß- und Kleinschreibung .
Die Zeilen ignorieren Leerzeichen immer von beiden Seiten NAN
, INF
, -INF
(unabhängig davon LC_CTYPE
). Andere alphabetische Zeichen können Leerzeichen von beiden Seiten ignorieren, abhängig vom GebietsschemaLC_COLLATE
LC_COLLATE=fr_FR.UTF-8
ignorieren (z. B. ignorieren, aber LC_COLLATE=us_EN.UTF-8
nicht ignorieren).
Wenn Sie also beliebige alphanumerische Zeichen sortieren, möchten Sie dies wahrscheinlich nicht-g
. Wenn Sie wirklich einen Vergleich der wissenschaftlichen Notation mit benötigen -g
, möchten Sie wahrscheinlich alphabetische und numerische Daten extrahieren und den Vergleich separat durchführen .
Wenn Sie nur eine normale Nummer benötigen (z 1, -1
) und dies für 0x/E/+ sorting
nicht wichtig halten, verwenden Sie einfach -n
genug:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-1000
-22
-13
-11
-010
-10
-5
-2
-1
-0.2
-0.12
-0.11
-0.1
0x1
0x11
0xb
+1
+11
+2
-a
-aa
--aa
-aaa
-b
baa
BAA
bbb
+ignore
inf
-inf
--inf
--inf
--inf-
--inf--
-inf--
--inf-a
naN
Nana
nani lol
--nnf
nnf--
nnn
None
uum
Zero cool
-zzz
1
1.1
1.234E10
5
11
Entweder -g
oder -n
, sich bewusst sein locale Wirkung . Sie können angeben möchten LC_NUMERIC
alsus_EN.UTF-8
zu vermeiden fr_FR.UTF-8 Art -
mit schwimmender Nummer fehlgeschlagen :
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=fr_FR.UTF-8 sort -n myfile
-10
-5
-2
-1
-1.1
-1.2
-0.1
-0.11
-0.12
-0.2
-a
+b
middle
-wwe
+zoo
1
1.1
Mit LC_NUMERIC=en_US.UTF-8
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=en_US.UTF-8 sort -n myfile
-10
-5
-2
-1.2
-1.1
-1
-0.2
-0.12
-0.11
-0.1
-a
+b
middle
-wwe
+zoo
1
1.1
Oder LC_NUMERIC=us_EN.UTF-8
zu gruppieren+|-|space
mit alpha
:
$ LC_COLLATE=fr_FR.UTF-8 LC_NUMERIC=us_EN.UTF-8 sort -n myfile
-0.1
a
b
a
b
+b
+zoo
-a
-wwe
middle
1
Sie möchten wahrscheinlich locale
bei der Verwendung angeben , sort
ob ein tragbares Skript geschrieben werden soll.
sort
nicht dieman
Seite, sondern dieinfo
Seite (info sort
) ist.