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
- aplawrence.com/Unixart/sort-vs-uniq.html
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 putkessauniq -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 vainip
-komennosta nyt. - +1 varten ” 9 kertaa 10 I ’ m itse asiassa putket
uniq -c
” (ja ehkä putkisto vielä kerransort -nr | head
). Mietin, mikä vastaasort | uniq
: ää Vimissä, kun sain selville, että Vimillä on komento:sort u
. Ja TILsort -u
on myös olemassa. - Huomaa, että on eroa käytettäessä
sort -n | uniq
jasort -n -u
. Esimerkiksisort -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
palauttaatest
, muttaecho -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ää osoitteelleuniq
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 ٠١٢٣, jotensort -u
säilyttäisi vain yhden kummastakin, kun taasuniq
(ei GNUuniq
, joka käyttäästrcoll()
(paitsi-i
)), ① on erilainen from ja 0123 eroavat ٠١٢٣: stä, jotenuniq
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 taasstrcmp()
ei välitä merkkeistä, koska se vertaa vain tavu-to-tavu. Joten se on toinen syy, miksisort -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
vaihtoehtosort
antaa ensimmäisen samanarvoisesti (katso man-sivu). Tätensort -fu
poimii jokaisen kirjainkoon ottamattoman ainutlaatuisen rivin ensimmäisen esiintymisen. Logiikka, jotasort
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