Oriunde văd pe cineva care are nevoie să obțină o listă sortată, unică, se conectează întotdeauna la sort | uniq. „Nu am văzut niciodată exemple în care cineva folosește sort -u în schimb. De ce nu? Care este diferența și de ce este mai bine să folosiți uniq decât steagul unic pentru a sorta?
Comentarii
- aplawrence.com/Unixart/sort-vs-uniq.html
Răspuns
sort | uniq exista înainte ca sort -u și este compatibil cu o gamă mai largă de sisteme, deși aproape toate sistemele moderne acceptă -u – este POSIX. Este în mare parte o revenire până în zilele în care sort -u nu exista (iar oamenii nu au tendința de a-și schimba metodele dacă modul în care știu continuă să funcționeze, uitați-vă la ifconfig vs. ip adoptare).
Probabil că cele două au fost îmbinate, deoarece eliminarea duplicatelor dintr-un fișier necesită sortare (cel puțin, în standard este un caz de utilizare extrem de obișnuit. De asemenea, este mai rapid intern ca urmare a faptului că puteți face ambele operații în același timp (și datorită faptului că nu necesită IPC între uniq și sort). Mai ales dacă fișierul este mare, sort -u va folosi probabil mai puține fișiere intermediare pentru a sorta datele.
Pe sistemul meu Obțin în mod constant rezultate de acest fel:
$ 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
De asemenea, nu maschează codul de returnare al sort, care poate fi important (în cochilii moderni există modalități de a obține acest lucru, de exemplu, bash „s $PIPESTATUS, dar acest lucru nu a fost” t întotdeauna adevărat).
Comentarii
- Tind să folosesc
sort | uniqdeoarece de 9 ori din 10, De fapt, ‘ mă duc launiq -c. - Rețineți că
sort -ua făcut parte din ediția a 7-a UNIX, circa 1979. Versiunilesortwithou Asistența pentru-usunt cu adevărat arhaice – sau au fost scrise fără atenție la standardul de facto înainte de POSIX ‘ s de jure standard. A se vedea, de asemenea, Stack Overflow Sortare & uniq în Linux shell din 2010. - +1 pentru că din
ip. Este ‘ s 2016 și această postare în 2013, dar știu doar despre comandaipacum. - +1 pentru ” de 9 ori 10 I ‘ m canalizând de fapt către
uniq -c” (și poate încă o dată canalizarea cătresort -nr | head). Mă întrebam care este echivalentulsort | uniqîn Vim când am aflat că Vim are comanda:sort u. Și TILsort -uexistă, de asemenea. - Rețineți că există o diferență atunci când utilizați
sort -n | uniqvs.sort -n -u. De exemplu, spațiile albe de urmărire și de conducere vor fi văzute ca duplicate desort -n -u, dar nu de primul!echo -e 'test \n test' | sort -n -ureturneazătest, darecho -e 'test \n test' | sort -n | uniqreturnează ambele linii.
Răspuns
O diferență este că uniq are o serie de opțiuni suplimentare utile, cum ar fi sărind câmpuri pentru comparație și numărând numărul de repetări ale unei valori. sort „s -u implementează doar funcționalitatea comenzii uniq fără ornamente.
Comentarii
- +0.49 pentru un răspuns util, dar aș spune-o ceva de genul ”
sort -unu se poate transmite ‘ launiqpentru a utiliza unele dintre acestea din urmă ‘ opțiuni utile, cum ar fi sări peste câmpuri pentru comparație și numărarea numărului de repetări. ” - +1 pentru a compensa naysayers, deoarece ” nu există ‘ nici o modalitate de a face acest lucru direct din sortare ” răspunde la întrebare …
Răspuns
Cu POSIX sort s și uniq s (GNU uniq în prezent nu este conformă în acest sens), există o diferență prin faptul că sort folosește algoritmul de asociere local pentru a compara șirurile (de obicei se va folosi strcoll() pentru a compara șirurile) în timp ce uniq verifică identitatea valorii octeților (va folosi de obicei strcmp()) ¹.
Acest lucru contează din cel puțin două motive .
-
În unele locații, în special pe sistemele GNU, există diferite caractere care sortează la fel. De exemplu, în localizarea en_US.UTF-8 pe un sistem GNU, toate ①②③④⑤⑥⑦⑧⑨⑩ … caracterele² și multe altele sortează la fel, deoarece ordinea lor de sortare nu este definită. 0123456789 cifre arabe sortează la fel ca Eastern Arabic Indic (s).
Pentru
sort -u, ① sortează la fel ca ② și 0123 la fel ca ٠١٢٣, astfel încâtsort -uar păstra doar unul din fiecare, în timp ce pentruuniq(nu GNUuniqcare foloseștestrcoll()(cu excepția-i)), ① este diferit din ② și 0123 diferit de ٠١٢٣, deciuniqar considera toate cele 4 unice. -
strcollpoate compara șiruri de caractere valide (comportamentul este nedefinit conform POSIX atunci când intrarea are secvențe de octeți care nu formează caractere valide) în timp cestrcmp()nu-i pasă despre caractere, deoarece face doar comparație octet-la-octet. Deci, acesta este un alt motiv pentru caresort -upoate să nu vă ofere toate liniile unice dacă unele dintre ele nu formează un text valid.sort|uniq, deși încă nespecificat la introducerea fără text, în practică este mai probabil să vă ofere linii unice din acest motiv.
În afară de aceste subtilități, un lucru care nu a fost remarcat până acum este că uniq compară linia întreagă lexical, în timp ce sort „s -u compară pe baza specificațiilor de sortare date pe linia de comandă.
$ 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
¹ Versiunile anterioare ale specificației POSIX au provocat confuzie, însă prin listarea variabilei LC_COLLATE ca una care afectează uniq, care a fost eliminată în ediția din 2018 și comportamentul clarificat în urma acelei discuții menționate mai sus. Consultați eroarea de grup Austin corespunzătoare
² 2019 editați . Cele de atunci au fost remediate, dar peste 95% din punctele de cod Unicode au încă o ordine nedefinită începând cu versiunea 2.30 a GNU libc . Puteți testa cu 🧙🧚🧛🧜🧝, de exemplu, în versiunile mai noi
Răspunde
Prefer să folosesc sort | uniq deoarece atunci când încerc să folosesc opțiunea -u (eliminați duplicatele) pentru a elimina duplicatele care implică șiruri de litere mari, nu este atât de ușor să înțelegeți rezultatul.
Notă: înainte de a putea rula exemplele de mai jos, trebuie să simulați secvența standard de asamblare C făcând următoarele:
LC_ALL=C export LC_ALL
De exemplu, dacă vreau să sortez un fișier și să elimin duplicatele, păstrând în același timp diferitele cazuri de șiruri.
$ 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?)
Această confuzie este rezolvată prin utilizarea opțiunii -u pentru a elimina duplicatele. Utilizarea uniq este mai previzibilă. Mai jos, mai întâi sortează și ignoră cazul și apoi îl trimite la uniq pentru a elimina duplicatele.
$ sort -f short | uniq Apple apple Pear pear
Comentarii
-
-uopțiuneasortgenerează primul de o alergare egală (vezi pagina man). Astfel,sort -fupreia prima apariție a fiecărei linii unice insensibile la majuscule. Logica pe caresorto folosește pentru a elimina duplicatele este previzibilă.
Răspuns
O altă diferență pe care am aflat-o astăzi este când sortez pe baza unui delimetru unde sort -u aplică steagul unic numai pe coloana cu care sortați.
$ 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
Comentarii
- Acest lucru este menționat într-un răspuns de la St é phane Chazelas, dar Îmi place exemplul dvs., așa că +1
- Vă mulțumim că ați subliniat @roaima, nu a fost ‘ foarte clar în acest răspuns