“Sort -u” ve “sort | arasındaki fark nedir? uniq”?


120

Her yerde, sıralı, benzersiz bir liste almak isteyen birisini görüyorum, onlar her zaman işe yarar sort | uniq. Bunun sort -uyerine birinin kullandığı hiçbir örnek görmedim . Neden olmasın? Aradaki fark nedir ve uniq kullanmak için sıralamada benzersiz bayrağa göre neden daha iyidir?


Yanıtlar:


120

sort | uniqdaha önce mevcuttu sort -uve daha geniş bir sistem yelpazesi ile uyumlu, neredeyse tüm modern sistemler destekliyor -uolsa da, POSIX. Çoğunlukla sort -uvarolmadığı günler için bir geri dönüş (ve insanlar bildikleri şekilde çalışmaya devam ederse yöntemlerini değiştirme eğiliminde değillerdir, sadece bakmaya ifconfigve ipevlat edinmeye bakarlar ).

İkisi büyük olasılıkla birleştirildi, çünkü bir dosya içindeki kopyaların kaldırılması sıralama gerektiriyor (en azından standart durumda) ve sıralamada oldukça yaygın bir kullanım durumuydu. Bu (ve o nedeniyle arasındaki IPC gerektirmez gerçeğine aynı anda her iki işlemleri yapabilmek olmanın bir sonucu olarak daha hızlı içten de uniqve sort). Özellikle dosya büyükse, sort -uverileri sıralamak için büyük olasılıkla daha az ara dosya kullanır.

Sistemimde sürekli şöyle sonuçlar alıyorum:

$ dd if=/dev/urandom of=/dev/shm/file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 8.95208 s, 11.7 MB/s
$ time sort -u /dev/shm/file >/dev/null

real        0m0.500s
user        0m0.767s
sys         0m0.167s
$ time sort /dev/shm/file | uniq >/dev/null

real        0m0.772s
user        0m1.137s
sys         0m0.273s

Aynı zamanda dönüş kodu maske değil sortönemli olabilir, (modern kabuklarda orada bu almak için yollar, örneğin, bash'ın $PIPESTATUSdizi, ancak bu her zaman doğru değildi).


31
Kullanmaya meyilliyim, sort | uniqçünkü 10 üzerinden 9 kez, gerçekten boru alıyorum uniq -c.
Plutor

5
Unutmayın sort -u, 779 UNIX’in bir parçasıydı, 1979’da. sortDesteği olmayan sürümler -ugerçekten arkaikti - ya da POSIX’in jüri standardı öncesi fiili standartlara dikkat edilmeden yazılmıştı. Ayrıca bakınız Taşma Taşması 2010'dan itibaren Linux kabuğundaki sıralama ve uniq .
Jonathan Leffler

3
Nedeniyle +1 ip. 2016 ve 2013'teki bu gönderi, ancak şimdi yalnızca ipemir hakkında bilgim var .
02

4
+1 "10 üzerinden 9 kez. Aslında boruya çekiyorum uniq -c" (ve belki bir kez daha boruya daldırıyorum sort -nr | head). sort | uniqVim'in :sort uemir aldığını öğrendiğimde Vim'in eşdeğeri olduğunu merak ediyordum . Ve TIL de sort -uvar.
Zhuoyun Wei

Kullanırken bir fark olduğunu unutmayın sort -n | uniqVS. sort -n -u. Örneğin, izleyen ve önde gelen boşluklar, eskiler tarafından kopyalanacak sort -n -u! echo -e 'test \n test' | sort -n -udöner test, ancak echo -e 'test \n test' | sort -n | uniqher iki satırı da döndürür.
mxmlnkn

46

Bir fark, uniqkarşılaştırma için alanları atlamak ve bir değerin tekrar sayısını saymak gibi çok sayıda faydalı ek seçeneğe sahip olmasıdır. sort'in -ubayrağı yalnızca süslenmemiş uniqkomutun işlevselliğini uygular .


3
Yararlı bir cevap için +0,49, ancak şunu söyleyebilirim: " Karşılaştırma için alanları atlamak ve tekrar sayısını saymak gibi alanların yararlı seçeneklerinden bazılarını kullanmak sort -uiçin çıktısı alınamaz uniq."
l0b0

15
"Çeşit doğrudan Bunu yapmanın bir yolu yoktur" çünkü 1 Naysayers dengelemek için yapar ... soruya cevap
Izkata

42

POSIX uyumlu ile sorts ve uniqs (GNU uniqşu anda bu konuda değil uyumludur), arada fark var ki sort(tipik kullanacak dizeleri karşılaştırmak için yerelin algoritma kullanır strcoll()iken dizeleri karşılaştırmak için) uniqbayt değeri kimlik kontrolleri (tipik kullanacağız strcmp()) .

Bu en az iki nedenden dolayı önemli.

  • Bazı yerlerde, özellikle GNU sistemlerinde, aynı sıralamada farklı karakterler vardır. Örneğin, bir GNU sistemindeki en_US.UTF-8 yerel ayarında, tüm ①②③④⑤⑥⑦⑧⑨⑩ ... karakterleri ve diğerleri, sıralama düzenleri tanımlanmadığından aynı şekilde sıralanır. 0123456789 arapça rakamları, Doğu Arapça Hintçe emsalleriyle aynı şekilde sıralanır (٠١٢٣٤٥٦٧٨٩).

    İçin sort -u① böylece ② ve 0123 ile aynı 0123 ile aynı sıralar sort -uiçin ise, sadece her birini elinde tutacak uniq(değil GNU uniqkullanır strcoll()(hariç -i)), ① farklıdır ② ve 0123 farklı 0123, bu yüzden uniqbütün dikkate alacağını 4 eşsiz.

  • strcollsadece strcmp()byte-byte karşılaştırması yaptığı için karakterleri önemsemezken sadece geçerli karakterlerin dizelerini karşılaştırabilir (giriş geçerli karakterleri oluşturmayan baytların dizileri olduğunda POSIX'e göre davranış tanımsızdır) . Bu yüzden sort -u, bazıları geçerli metin oluşturmuyorsa, size tüm benzersiz satırları verememenin başka bir nedeni . sort|uniqMetin dışı girdilerde hala belirtilmemiş olsa da, pratikte bu nedenle size benzersiz çizgiler verme olasılığı daha yüksektir.

O inceliklerini yanında, bugüne kadar dikkat edilmemiştir bir şey olduğunu uniqederken, lexically bütün çizgi karşılaştırır sort'ın -ukomut satırında verilen sıralama özelliğine dayalı karşılaştırır.

$ printf '%s\n' 'a b' 'a c' | sort -uk 1,1
a b
$ printf '%s\n' 'a b' 'a c' | sort -k 1,1 | uniq
a b
a c

$ printf '%s\n' 0 -0 +0 00 '' | sort -n | uniq
0
-0
+0
00

$ printf '%s\n' 0 -0 +0 00 '' | sort -nu
0

9

Kullanmayı tercih ediyorum, sort | uniqçünkü -ukarışık vaka dizeleri içeren kopyaları kaldırmak için (kopyaları ortadan kaldır) seçeneğini kullanmaya çalıştığımda , sonucu anlamak o kadar kolay değil.

Not: Aşağıdaki örnekleri çalıştırmadan önce, aşağıdakileri yaparak standart C harmanlama sırasını simüle etmeniz gerekir:

LC_ALL=C
export LC_ALL

Örneğin, bir dosyayı sıralamak ve kopyaları kaldırmak istersem, aynı zamanda, farklı dizelerdeki farklılıkları farklı tutmak için.

$ cat short      #file to sort
Pear
Pear
apple
pear
Apple

$ sort short     #normal sort (in normal C collating sequence)
Apple            #the lower case words are at the end
Pear
Pear
apple
pear

$ sort -f short  #correctly sorts ignoring the C collating order
Apple            #but duplicates are still there
apple
Pear
Pear
pear

$ sort -fu short #By adding the -u option to remove duplicates it is 
apple            #difficult to ascertain the logic that sort uses to remove
Pear             #duplicates(i.e., why did it remove pear instead of Pear?)

Bu karışıklık, -ukopyaları kaldırma seçeneği kullanılmadan çözülür . Kullanımı uniqdaha öngörülebilirdir. Aşağıdaki, ilk önce durumu sıralar ve yok sayar ve sonra uniqyinelemeleri kaldırmak için iletir.

$ sort -f short | uniq
Apple
apple
Pear
pear

2
-uÇıktı seçeneği eşit bir sortçalışmanın ilkidir (man sayfasına bakınız). Böylece sort -fuher büyük / küçük harfe duyarlı olmayan benzersiz çizginin ilk oluşumunu yakalar. Kopyaları sortkaldırmak için kullanılan mantık tahmin edilebilirdir.
pallxk 09:15 '

3

Bugün tespit ettiğim bir diğer fark sort -u, benzersiz bayrağını yalnızca sıraladığınız sütunda uygulayan bir sınırlayıcıya dayalı sıralamadır.

$ cat input.csv
3,World,1
1,Hello,1
2,Hello,1

$ cat input.csv | sort -t',' -k2 -u
1,Hello,1
3,World,1

$ cat input.csv | sort -t',' -k2 | uniq
1,Hello,1
2,Hello,1
3,World,1

Bu Stéphane Chazelas'ın bir cevabından bahsediyor ama ben senin örneğini çok beğendim +1
roaima

@Roaima'yı işaret ettiğiniz için teşekkür ederiz, bu cevabında çok net değildi
Stefanos Chrs
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.