Mitä eroa on “ sort -u ” ja “ sort | uniq ”?

Kaikkialla, missä näen jonkun tarvitsevan lajitellun, yksilöllisen luettelon, he aina lähettävät sort | uniq -palveluun. En ole koskaan nähnyt esimerkkejä, joissa joku käyttää sen sijaan sort -u. Miksi ei? Mikä ero on ja miksi lajittelussa on parempi käyttää uniq: tä kuin ainutlaatuista lippua?

Kommentit

vastaus

sort | uniq oli olemassa ennen sort -u, ja on yhteensopiva laajempien järjestelmien kanssa, vaikka melkein kaikki modernit järjestelmät tukevat -u – se POSIXia. Se on enimmäkseen takaisku. päiviin, jolloin sort -u ei ollut olemassa (ja ihmisillä ei ole tapana muuttaa tapojaan, jos tapa, jonka he tietävät, toimii edelleen, katso vain ifconfig vs. ip hyväksyminen).

Kaksi yhdistettiin todennäköisesti, koska kaksoiskappaleiden poistaminen tiedostosta vaatii lajittelua (ainakin standardissa tapaus), ja se on erittäin yleinen lajittelutapa. Se on myös nopeampi sisäisesti, koska molemmat toiminnot voidaan suorittaa samanaikaisesti (ja koska se ei vaadi IPC: tä välillä uniq ja sort). Varsinkin jos tiedosto on iso, sort -u käyttää todennäköisesti vähemmän välitiedostoja tietojen lajitteluun.

Järjestelmässäni Saan jatkuvasti tällaisia tuloksia:

$ 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 

Se ei myöskään peitä sort -palautuskoodia voi olla tärkeä (nykyaikaisissa kuorissa on tapoja saada tämä, esimerkiksi bash ”s $PIPESTATUS -taulukko, mutta tätä ei ollut aina totta).

Kommentit

  • Käytän yleensä sort | uniq, koska 9 kertaa 10: stä, Olen ’ m oikeastaan putkessa uniq -c.
  • Huomaa, että sort -u oli osa 7. painoksen UNIXia, noin 1979. sort withou -ohjelman versiot -u -tuki on todella arkaaista – tai kirjoitettiin kiinnittämättä huomiota tosiasialliseen standardiin ennen POSIX ’ s de jure -standardia. Katso myös pinon ylivuoto Lajittele & uniq Linux-kuoressa vuodesta 2010.
  • +1, koska ip. Se ’ s 2016 ja tämä viesti vuonna 2013, mutta tiedän vain ip -komennosta nyt.
  • +1 varten ” 9 kertaa 10 I ’ m itse asiassa putket uniq -c ” (ja ehkä putkisto vielä kerran sort -nr | head). Mietin, mikä vastaa sort | uniq: ää Vimissä, kun sain selville, että Vimillä on komento :sort u. Ja TIL sort -u on myös olemassa.
  • Huomaa, että on eroa käytettäessä sort -n | uniq ja sort -n -u. Esimerkiksi sort -n -u: n jäljessä olevat ja johtavat tyhjät tilat nähdään kaksoiskappaleina, mutta edelliset eivät! echo -e 'test \n test' | sort -n -u palauttaa test, mutta echo -e 'test \n test' | sort -n | uniq palauttaa molemmat rivit.

Vastaus

Yksi ero on, että uniq -palvelussa on useita hyödyllisiä lisäasetuksia, kuten ohitetaan kentät vertailua varten ja lasketaan arvon toistojen määrä. sort ”s -u -lippu toteuttaa vain koristamattoman uniq -komennon toiminnot.

Kommentit

  • +0,49 hyödyllistä vastausta varten, mutta sanoin sen esimerkiksi ” sort -u ei ’ voida välittää osoitteelle uniq käyttääksesi joitain jälkimmäisistä ’ hyödyllisiä vaihtoehtoja, kuten ohittaa kentät vertailua varten ja laskea toistojen määrä. ”
  • +1 kompensoidaksesi naysayers, koska ” siellä ’ ei ole mitään tapaa tehdä tätä suoraan lajittelusta ” vastaa kysymykseen …

Vastaa

POSIX-yhteensopivan sort s ja uniq s (GNU uniq ei ole tällä hetkellä yhteensopiva tältä osin), siellä ”ero siinä, että sort käyttää kielen vertailualgoritmia merkkijonojen vertaamiseen (käyttää tyypillisesti strcoll() merkkijonojen vertaamiseen), kun uniq tarkistaa tavuarvon identiteetin (käyttää yleensä strcmp()) ¹.

Tällä on merkitystä ainakin kahdesta syystä .

  • Joillakin alueilla, etenkin GNU-järjestelmissä, on erilaisia merkkejä, jotka lajittelevat saman. Esimerkiksi GNU-järjestelmän kielellä en_US.UTF-8 kaikki ①②③④⑤⑥⑦⑧⑨⑩ … merkit² ja monet muut lajittelevat saman, koska niiden lajittelujärjestystä ei ole määritelty. Arabialaiset 0123456789-numerot lajittelevat samanlaiset kuin niiden itä-arabialaiset intialaiset -verkot (٠١٢٣٤٥٦٧٨٩).

    sort -u, ① lajittelee samat kuin ② ja 0123 samat kuin ٠١٢٣, joten sort -u säilyttäisi vain yhden kummastakin, kun taas uniq (ei GNU uniq, joka käyttää strcoll() (paitsi -i)), ① on erilainen from ja 0123 eroavat ٠١٢٣: stä, joten uniq pitää kaikkia 4 ainutlaatuisena.

  • strcoll voi verrata vain kelvollisten merkkien merkkijonoja (käyttäytymistä ei määritellä POSIX: n mukaan, kun syötteessä on tavusekvenssejä, jotka eivät muodosta kelvollisia merkkejä), kun taas strcmp() ei välitä merkkeistä, koska se vertaa vain tavu-to-tavu. Joten se on toinen syy, miksi sort -u ei välttämättä anna sinulle kaikkia ainutlaatuisia rivejä, jos jotkut niistä eivät muodosta kelvollista tekstiä. sort|uniq, vaikka sitä ei vielä ole määritelty muussa kuin tekstinsyötössä, käytännössä se antaa sinulle todennäköisesti ainutlaatuisia rivejä tästä syystä.

Näiden hienovaraisuuksien lisäksi yksi asia, jota ei ole toistaiseksi huomattu, on se, että uniq vertaa koko viivaa leksikaalisesti, kun taas sort ”s -u vertaa komentorivillä annettujen lajittelumääritysten perusteella.

$ 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 

¹ Aikaisemmat POSIX-tekniset versiot aiheuttivat hämmennystä, kun kuitenkin listattiin LC_COLLATE -muuttuja sellaiseksi, joka vaikuttaa uniq -muuttujaan, joka poistettiin vuoden 2018 versiosta ja käyttäytyminen selkiytyi edellä mainitun keskustelun jälkeen. Katso vastaava Austin-ryhmän vika

² 2019 muokkaa . Ne on sittemmin korjattu, mutta yli 95% Unicode-koodipisteistä on edelleen määrittelemätön järjestys GNU libc: n versiosta 2.30 alkaen. Voit testata sen sijaan 🧙🧚🧛🧜🧝: llä, esimerkiksi uudemmissa versioissa

Vastaa

Haluan käyttää sort | uniq, koska kun yritän käyttää -u (poista kaksoiskappaleet) -vaihtoehtoa poistaa kaksoiskappaleet, joihin liittyy sekakokoisia merkkijonoja, ei ole niin helppoa ymmärrä tulos.

Huomaa: ennen kuin voit suorittaa alla olevia esimerkkejä, sinun on simuloitava C-vakiolajittelujärjestys seuraavasti:

LC_ALL=C export LC_ALL 

Esimerkiksi, jos haluan lajitella tiedoston ja poistaa kaksoiskappaleet samalla, kun pidän merkkijonojen eri tapaukset erillisinä.

$ 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?) 

Tämä sekaannus ratkaistaan, jos kaksoiskappaleiden poistamiseen ei käytetä vaihtoehtoa -u. uniq -toiminnon käyttö on ennakoitavampaa. Seuraava lajittelee ja ohittaa ensin tapauksen ja välittää sen sitten uniq -sivustolle kaksoiskappaleiden poistamiseksi.

$ sort -f short | uniq Apple apple Pear pear 

Kommentit

  • -u vaihtoehto sort antaa ensimmäisen samanarvoisesti (katso man-sivu). Täten sort -fu poimii jokaisen kirjainkoon ottamattoman ainutlaatuisen rivin ensimmäisen esiintymisen. Logiikka, jota sort käyttää kaksoiskappaleiden poistamiseen, on ennustettavissa.

Vastaa

Toinen ero, jonka huomasin tänään, on lajittelu erottimen perusteella, jossa sort -u käyttää yksilöllistä lippua vain sarakkeessa, jonka kanssa lajittelet.

$ 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 

kommentit

  • Tämä mainitaan St é phane Chazelasin vastauksessa Pidän esimerkistäsi, joten +1
  • kiitos, että osoitit @roaima, se ei ollut ’ t kovin selvä vastauksessa

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *