Gnu sıralamasında --general-numeric-sort ve --numeric-sort seçenekleri arasındaki fark nedir


113

sortiki tür sayısal sıralama sağlar. Bu man sayfasından:

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

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

Fark ne?


17
Tam dokümantasyon unutmayın sortdeğildir mansayfa ama infosayfası ( info sort).
a3nm

Yanıtlar:


85

Genel sayısal sıralama, sayıları kayan sayılarla karşılaştırır, bu bilimsel gösterime izin verir, örneğin 1.234E10, ancak daha yavaştır ve yuvarlama hatasına tabidir (1.2345678, 1.2345679'dan sonra gelebilir), sayısal sıralama, 10'un 9'dan sonra geldiğini bilen normal bir alfabetik sıralamadır.

Bkz. Http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html

'-g' '--general-numeric-sort' '--sort = general-numeric' Her satırın önekini çift duyarlıklı kayan noktalı sayıya dönüştürmek için standart C işlevi strtod kullanarak sayısal olarak sıralayın. Bu, kayan nokta sayılarının 1.0e-34 ve 10e100 gibi bilimsel gösterimde belirtilmesine olanak tanır. LC_NUMERIC yerel ayarı, ondalık nokta karakterini belirler. Taşma, yetersizlik veya dönüştürme hatalarını bildirmeyin. Aşağıdaki harmanlama sırasını kullanın: Sayılarla başlamayan çizgiler (tümü eşit kabul edilir). NaN'ler (IEEE kayan nokta aritmetiğinde "Sayı Değil" değerleri) tutarlı, ancak makineye bağlı bir sırada. Eksi sonsuzluk. Artan sayısal sırada sonlu sayılar (-0 ve +0 eşittir). Artı sonsuzluk.

Bu seçeneği yalnızca başka alternatif yoksa kullanın; --numeric-sort (-n) 'den çok daha yavaştır ve kayan noktaya dönüştürürken bilgi kaybedebilir.

'-n' '--numeric-sort' '--sort = numeric' Sayısal olarak sıralayın. Sayı her satırdan başlar ve isteğe bağlı boşluklardan, isteğe bağlı bir '-' işaretinden ve muhtemelen binlik ayırıcılarla ayrılmış sıfır veya daha fazla basamaktan, isteğe bağlı olarak ondalık nokta karakteri ve sıfır veya daha fazla basamaktan oluşur. Boş bir sayı '0' olarak kabul edilir. LC_NUMERIC yerel ayarı, ondalık nokta karakterini ve binlik ayırıcıyı belirtir. Varsayılan olarak boşluk, boşluk veya sekmedir, ancak LC_CTYPE yerel ayarı bunu değiştirebilir.

Karşılaştırma kesindir; yuvarlama hatası yoktur.

Ne baştaki '+' ne de üstel gösterim tanınır. Bu tür dizeleri sayısal olarak karşılaştırmak için --general-numeric-sort (-g) seçeneğini kullanın.


2
Teşekkürler. Adamın ve bilgi sayfalarının içinde bunun olmaması garip. Ayrıca gnu.org/software/coreutils/manual/html_node/index.html hakkında da bilgim yoktu .
Trenton

6
Bu şeyler benim için çalışmıyor. R1 R2 R10 R15 gibi içeriğe sahip üçüncü bir sütuna sahip bir dosyayı sıralıyorum. -k3.2nVeya kullanarak -k3.2g, daha R10önce sıralıyor R2. Sıralama sayısal değil, sözlükbilimseldir. İkinci karakterden itibaren alana bir sayı olarak davranmasını bekliyorum.
Kaz

6
@Kaz: sortanahtar özellikleri. gerçekten bizanslılar - kısası şudur: alandan önceki boşluklar alanın bir parçası olarak kabul edilir , bu yüzden karakter. dizin 1, alanın gerçek ilk karakterini değil, alandan önceki (ilk) boşluğa işaret eder. Karakterin sonuna ekleyin. index b: Bu sorunu, yani düzeltmek için -k 3.2bn,3(o notu küresel -b seçenek yok değil bu durumda işi). Ayrıca ,3, yalnızca 3. alanın kullanılmasını sağlayan eklenmiş olana da dikkat edin - 2. alan dizini olmadan , tüm satırın geri kalanı kullanılır.
mklement0

11

Yerel ayarlarınıza dikkat etmelisiniz. Örneğin, kayan bir sayıyı sıralamayı düşünebilirsiniz (2.2 gibi), oysa yerel ayarınız virgül kullanılmasını bekleyebilir (2,2 gibi).

Bu forumda bildirildiği gibi , -n veya -g bayraklarını kullanarak yanlış sonuçlara sahip olabilirsiniz.

Benim durumumda kullanıyorum:

LC_ALL=C sort -k 6,6n file

6. sütunu içeren sıralamayı yapmak için:

2.5
3.7
1.4

elde etmek üzere

1.4
2.5
3.7

2
LANG = C olsa bile, -nvirgülü binlik ayırıcı olarak tanıyamıyorum - "1.000", "1" ile aynı kabul edilir.
Scott

1
Bu LC_ALL = C olmalıdır.
Stuart P. Bentley

@Scott: Aslında, binlerce ayırıcı tanınmaz: en uzun önek mantığını sortkullanır : satırın / anahtarın sayı olarak tanıdığı en uzun kısmı kullanılır; radix karakteri olarak kullanan bir yerel ayarda okumayı durdurur . .,
mklement0

@ StuartP.Bentley: LC_ALL=Cgerçekten de en sağlam seçim; ancak, LC_ALLbahis setine gelmezse LANG=Cde işe yarayacaktır.
mklement0

1
İyi bir nokta, ancak LANG=C sort -k 6,6n filehem daha basit hem de ortam değişkenini belirli bir komuta ayarlamanın etkisini yerelleştiriyorLANG .
mklement0

0

-gBilimsel gösterime izin veren kabul edilen cevaba ek olarak, istenmeyen davranışlara neden olma ihtimali en yüksek olan kısmı göstermek istiyorum.

İle -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

Bak zooburada, üç önemli şeylerden:

  • Satır NAN(örn. NanaVe nani lol) ile başlar veya -INF(tek çizgi, değil --INF) sona hareket eder, ancak rakamlardan önce gelir. İken INFbasamak sonra geçen geçişle çünkü o sonsuzluk demektir .

  • NAN, INFVe -INFvardır harf duyarsız .

  • Çizgiler , her zaman her iki yanından boşluk göz ardı NAN, INF, -INF (ne olursa olsun LC_CTYPE). Diğer alfabetikler, her iki taraftaki beyaz boşluğu yok sayabilir LC_COLLATE(örneğin, LC_COLLATE=fr_FR.UTF-8görmezden gelin ama LC_COLLATE=us_EN.UTF-8yok saymayın).

Dolayısıyla, rastgele alfasayısal bir sıralama yapıyorsanız, muhtemelen istemezsiniz -g. Gerçekten bilimsel gösterim karşılaştırmasına ihtiyacınız varsa -g, muhtemelen alfabe ve sayısal verileri çıkarmak ve ayrı ayrı karşılaştırma yapmak istersiniz .

Yalnızca sıradan sayı (örneğin 1, -1) sıralamasına ihtiyacınız varsa ve 0x/E/+ sortingbunun önemli olmadığını düşünüyorsanız, -nyeterince kullanı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

Yerel etkiden biri -gveya -nfarkında olun . Sen belirtmek isteyebilirsiniz olarak fr_FR.UTF-8 çeşit kaçınmak için numara başarısız Kayan :LC_NUMERICus_EN.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

İle 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

Veya LC_NUMERIC=us_EN.UTF-8şunlarla gruplandırmak +|-|spaceiçin 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

Taşınabilir komut dosyası yazmak isteyip istemediğinizi muhtemelen localene zaman kullanmak istediğinizi belirtmek sortistersiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.