gnu sortの--general-numeric-sortオプションと--numeric-sortオプションの違いは何ですか


113

sort2種類の数値ソートを提供します。これはmanページからです:

   -g, --general-numeric-sort
          compare according to general numerical value

   -n, --numeric-sort
          compare according to string numerical value

違いは何ですか?


17
の完全なドキュメントはページでsortはなくページ()であることに注意してください。maninfoinfo sort
a3nm 2012

回答:


85

一般的な数値ソートは、数値を浮動小数点数として比較します。これにより、たとえば1.234E10などの科学表記が可能になりますが、遅くなり、丸めエラーが発生します(1.2345678は1.2345679の後に来る可能性があります)。

http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.htmlを参照してください

'-g' '--general-numeric-sort' '--sort = general-numeric'標準のC関数strtodを使用して数値でソートし、各行のプレフィックスを倍精度浮動小数点数に変換します。これにより、1.0e-34や10e100のように、浮動小数点数を科学表記で指定できます。LC_NUMERICロケールが小数点文字を決定します。オーバーフロー、アンダーフロー、または変換エラーを報告しません。次の照合シーケンスを使用します。数字で始まらない行(すべて等しいと見なされます)。NaN(IEEE浮動小数点演算の「数値ではない」値)は、一貫しているがマシンに依存する順序で。マイナス無限大。昇順の有限数(-0と+0が等しい)。プラス無限大。

このオプションは、代替手段がない場合にのみ使用してください。--numeric-sort(-n)よりもはるかに低速であり、浮動小数点に変換するときに情報が失われる可能性があります。

'-n' '--numeric-sort' '--sort = numeric'数値でソートします。番号は各行から始まり、オプションのブランク、オプションの「-」記号、および千以上の区切り記号で区切られたゼロ以上の数字で構成され、オプションでその後に小数点文字とゼロ以上の数字が続きます。空の数値は「0」として扱われます。LC_NUMERICロケールは、小数点文字と桁区切り記号を指定します。デフォルトでは、空白はスペースまたはタブですが、LC_CTYPEロケールはこれを変更できます。

比較は正確です。丸め誤差はありません。

先頭の「+」も指数表記も認識されません。このような文字列を数値で比較するには、-general-numeric-sort(-g)オプションを使用します。


2
ありがとう。manとinfoページにはこれが含まれていないのは奇妙です。また、gnu.org/software/coreutils/manual/html_node/index.htmlについても知りませんでした
トレントン

6
これはうまくいきません。R1 R2 R10 R15のような内容の3番目の列を持つファイルをソートしています。-k3.2nまたはのいずれかを使用すると-k3.2gR10前にソートされR2ます。ソートは数値ではなく辞書式です。2文字目以降を数値として扱うことを期待しています。
Kaz 2012年

6
@Kaz:sortの主な仕様。本当にビザンチンです-短いです:フィールドの前の空白はフィールドの一部と見なされるので、charです。インデックス1は、フィールドの実際の最初の文字ではなく、フィールドの前の(最初の)空白を指します。charをサフィックスします。bつまり、この問題を修正するためにインデックスを付けます-k 3.2bn,3(この場合、グローバル -bオプションは機能しませ)。また、が追加され,3ていることに注意してください。これにより、3番目のフィールドのみが使用されます。2番目のフィールドインデックスがなければ、行全体残りが使用されます。
mklement0 2013

11

ロケールに注意する必要があります。たとえば、ロケールでは(2.2などの)浮動小数点数をソートする予定があるかもしれませんが、ロケールではコンマ(2、2など)の使用を想定している場合があります。

このフォーラムで報告されているように、-nまたは-gフラグを使用すると、誤った結果になる可能性があります。

私の場合、私は使用します:

LC_ALL=C sort -k 6,6n file

以下を含む6番目の列をソートするには、

2.5
3.7
1.4

を手に入れるために

1.4
2.5
3.7

2
LANG = Cを使用しても、-nコンマを3桁ごとの区切り文字として認識できません。「1,000」は「1」と同じように扱われます。
スコット

1
LC_ALL = Cである必要があります。
スチュアートP.ベントレー

@Scottは:確かに、桁区切りが認識されていません。sort用途最長プレフィックスロジック:番号が使用されているとして、それが認識するライン/キーの最長の一部を、.基数文字として使用するロケールでは、で読み取りを停止し,ます。
mklement0

@ StuartP.Bentley:LC_ALL=C確かに最も堅牢な選択です。ただし、LC_ALL賭けが設定されていない場合でもLANG=C機能します。
mklement0

1
良い点ですが、環境変数を設定する効果を特定のコマンドにローカライズするだけでなくLANG=C sort -k 6,6n file、よりシンプルです。LANG
mklement0

0

言及した受け入れられた答えに加えて -g科学的記法を許可すること、私は望ましくない動作を引き起こす可能性が最も高い部分を示したいと思います。

-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

zooここで、3つの重要な点を見てください。

  • 行はNAN(例:Nanaand nani lol)または-INF(シングルダッシュ、ではなく--INF)で始まり、数字の前に移動します。無限を意味するINFので数字の後の最後に移動しながら。

  • NANINF-INFされているケース小文字を区別しません

  • ラインは常にいずれかの側から空白を無視するNANINF-INF(関係なくLC_CTYPE)。他のアルファベットは、ロケールに依存するどちら側からでも空白を無視することがありますLC_COLLATE(たとえば、LC_COLLATE=fr_FR.UTF-8無視するがLC_COLLATE=us_EN.UTF-8無視しない)。

したがって、任意の英数字をソートする場合は、おそらく必要ありません-g。との科学表記法の比較が本当に必要な場合は-g、アルファベットと数値のデータを抽出して、別々に比較することをお勧めします。

通常の数値(例1, -1:)の並べ替えだけが必要で、それ0x/E/+ sortingが重要ではないと感じる場合は、-n十分に使用してください:

$ 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

-gまたはのいずれかで-nロケールの影響に注意してください。あなたは指定できますLC_NUMERICようus_EN.UTF-8 fr_FR.UTF-8ソートを避けるために-失敗した浮動番号とを

$ 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

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

またはLC_NUMERIC=us_EN.UTF-8グループ化+|-|spaceするには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

ポータブルスクリプトを作成するlocale場合は、使用するときに指定する必要がありますsort

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.