Overal waar ik zie dat iemand een gesorteerde, unieke lijst nodig heeft, sluizen ze altijd naar sort | uniq
. Ik heb nog nooit voorbeelden gezien waarin iemand sort -u
gebruikt. Waarom niet? Wat is het verschil, en waarom is het beter om uniq te gebruiken dan de unieke vlag om te sorteren?
Reacties
- aplawrence.com/Unixart/sort-vs-uniq.html
Antwoord
sort | uniq
bestond voordat sort -u
, en is compatibel met een groter aantal systemen, hoewel bijna alle moderne systemen -u
ondersteunen – het is POSIX. Het is meestal een erfenis naar de dagen dat sort -u
niet “bestond (en mensen niet de neiging hebben om hun methoden te veranderen als de manier die ze kennen nog steeds werkt, kijk maar naar ifconfig
vs. ip
adoptie).
De twee zijn waarschijnlijk samengevoegd omdat het verwijderen van duplicaten in een bestand sortering vereist (tenminste, in de standaard case), en is een zeer veel voorkomende soort gebruiksscenario. Het is ook intern sneller omdat je beide bewerkingen tegelijkertijd kunt uitvoeren (en omdat het geen IPC vereist tussen uniq
en sort
). Vooral als het bestand groot is, zal sort -u
waarschijnlijk minder tussenliggende bestanden gebruiken om de gegevens te sorteren.
Op mijn systeem Ik krijg consequent de volgende resultaten:
$ 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
Het maskeert ook niet de retourcode van sort
, die kan belangrijk zijn (in moderne shells zijn er manieren om dit te krijgen, bijvoorbeeld bash
“s $PIPESTATUS
array, maar dit was niet” t altijd waar).
Reacties
- Ik gebruik meestal
sort | uniq
omdat 9 van de 10 keer, Ik ‘ m eigenlijk doorgeleid naaruniq -c
. - Merk op dat
sort -u
maakte deel uit van 7th Edition UNIX, circa 1979. Versies vansort
zonder t ondersteuning voor-u
is echt archaïsch – of werd geschreven zonder aandacht voor de de facto standaard vóór POSIX ‘ s de jure standaard. Zie ook Stack Overflow Sorteer & uniq in Linux-shell uit 2010. - +1 omdat van
ip
. Het is ‘ s 2016 en dit bericht in 2013, maar ik weet nu alleen van hetip
commando. - +1 voor ” 9 keer 10 keer ik ‘ m eigenlijk doorsluizen naar
uniq -c
” (en misschien nog een keer doorsluizen naarsort -nr | head
). Ik vroeg me af wat het equivalent is vansort | uniq
in Vim toen ik ontdekte dat Vim een:sort u
commando heeft. En TILsort -u
bestaat ook. - Merk op dat er een verschil is tussen het gebruik van
sort -n | uniq
ensort -n -u
. Achter- en voorloopspaties worden bijvoorbeeld als duplicaten gezien doorsort -n -u
maar niet door de eerste!echo -e 'test \n test' | sort -n -u
retourneerttest
, maarecho -e 'test \n test' | sort -n | uniq
retourneert beide regels.
Antwoord
Een verschil is dat uniq
een aantal handige aanvullende opties heeft, zoals velden overslaan voor vergelijking en het tellen van het aantal herhalingen van een waarde. sort
“s -u
vlag implementeert alleen de functionaliteit van de onopgesmukte uniq
commando.
Reacties
- +0.49 voor een nuttig antwoord, maar ik zou het zoiets als ” De uitvoer van
sort -u
kan ‘ t worden doorgegeven aanuniq
om enkele van de laatste ‘ s handige opties, zoals het overslaan van velden voor vergelijking en het tellen van het aantal herhalingen. ” - +1 om de nee-zeggers omdat ” daar ‘ is geen manier om dit rechtstreeks te doen vanuit sort ” beantwoordt de vraag …
Antwoord
Met POSIX-compatibel sort
s en uniq
s (GNU uniq
voldoet momenteel niet in dat opzicht), er is een verschil in dat sort
het sorteeralgoritme van de landinstelling gebruikt om strings te vergelijken (gebruikt doorgaans strcoll()
om strings te vergelijken) terwijl uniq
controleert op byte-waarde identiteit (gebruikt doorgaans strcmp()
) ¹.
Dat is belangrijk om ten minste twee redenen .
-
In sommige landinstellingen, vooral op GNU-systemen, zijn er verschillende karakters die hetzelfde sorteren. Bijvoorbeeld, in de en_US.UTF-8 locale op een GNU-systeem, alle ①②③④⑤⑥⑦⑧⑨⑩ … karakters² en vele anderen sorteren hetzelfde omdat hun sorteervolgorde niet gedefinieerd is. De 0123456789 Arabische cijfers worden op dezelfde manier gesorteerd als hun Oost-Arabische Indische tegenhangers (٠١٢٣٤٥٦٧٨٩).
Voor
sort -u
, ① sorteert hetzelfde als ② en 0123 hetzelfde als ٠١٢٣ dussort -u
behoudt slechts één van elk, terwijl vooruniq
(niet GNUuniq
diestrcoll()
gebruikt (behalve met-i
)), ① is anders van ② en 0123 verschillen van ٠١٢٣, dusuniq
zou alle 4 als uniek beschouwen. -
strcoll
kan alleen strings van geldige tekens vergelijken (het gedrag is ongedefinieerd volgens POSIX wanneer de invoer reeksen bytes heeft die geen geldige tekens vormen) terwijlstrcmp()
het niet kan schelen over tekens omdat het alleen byte-naar-byte-vergelijking doet. Dus dat “is nog een reden waaromsort -u
je misschien niet alle unieke regels geeft als sommige ervan geen geldige tekst vormen.sort|uniq
, hoewel nog steeds niet gespecificeerd bij niet-tekstinvoer, geeft het in de praktijk om die reden waarschijnlijk meer unieke regels.
Afgezien van deze subtiliteiten, is een ding dat tot nu toe niet “niet is opgemerkt” dat uniq
de hele regel lexicaal vergelijkt, terwijl sort
“s -u
vergelijkt op basis van de sorteerspecificatie op de opdrachtregel.
$ 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
¹ Eerdere versies van de POSIX-specificatie veroorzaakten echter verwarring door de LC_COLLATE
-variabele op te sommen als een die van invloed was op uniq
, die in de 2018-editie en het gedrag verduidelijkt naar aanleiding van de hierboven genoemde discussie. Zie de overeenkomstige Austin-groepsbug
² 2019 bewerk . Die zijn sindsdien hersteld, maar meer dan 95% van de Unicode-codepunten hebben nog steeds een ongedefinieerde volgorde vanaf versie 2.30 van de GNU libc . U kunt in plaats daarvan testen met 🧙🧚🧛🧜🧝, bijvoorbeeld in nieuwere versies
Answer
Ik gebruik liever sort | uniq
want als ik de optie -u
(verwijder duplicaten) probeer te gebruiken om duplicaten te verwijderen met verschillende hoofdletters, is het niet zo eenvoudig om begrijp het resultaat.
Opmerking: voordat u de onderstaande voorbeelden kunt uitvoeren, moet u de standaard C-sorteervolgorde simuleren door het volgende te doen:
LC_ALL=C export LC_ALL
Als ik bijvoorbeeld een bestand wil sorteren en duplicaten wil verwijderen, terwijl ik tegelijkertijd de verschillende gevallen van strings gescheiden wil houden.
$ 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?)
Deze verwarring wordt opgelost door de optie -u
niet te gebruiken om duplicaten te verwijderen. Het gebruik van uniq
is voorspelbaarder. Het onderstaande sorteert en negeert eerst het hoofdlettergebruik en geeft het vervolgens door aan uniq
om de duplicaten te verwijderen.
$ sort -f short | uniq Apple apple Pear pear
Opmerkingen
-
-u
optie vansort
geeft de eerste van een gelijke run (zie man-pagina). Dussort -fu
pikt de eerste keer op van elke niet-hoofdlettergevoelige unieke regel. De logica diesort
gebruikt om duplicaten te verwijderen, is voorspelbaar.
Antwoord
Een ander verschil dat ik vandaag ontdekte, is bij het sorteren op basis van een scheidingsteken waarbij sort -u
de unieke vlag alleen toepast op de kolom waarmee u sorteert.
$ 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
Reacties
- Dit wordt vermeld in een antwoord van St é phane Chazelas maar Ik vind je voorbeeld leuk, dus +1
- Bedankt dat je hebt gewezen op @roaima, het was niet ‘ t erg duidelijk in dat antwoord