Wat is het verschil tussen “ sort -u ” en “ sort | uniq ”?

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

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 naar uniq -c.
  • Merk op dat sort -u maakte deel uit van 7th Edition UNIX, circa 1979. Versies van sort 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 het ip commando.
  • +1 voor ” 9 keer 10 keer ik ‘ m eigenlijk doorsluizen naar uniq -c ” (en misschien nog een keer doorsluizen naar sort -nr | head). Ik vroeg me af wat het equivalent is van sort | uniq in Vim toen ik ontdekte dat Vim een :sort u commando heeft. En TIL sort -u bestaat ook.
  • Merk op dat er een verschil is tussen het gebruik van sort -n | uniq en sort -n -u. Achter- en voorloopspaties worden bijvoorbeeld als duplicaten gezien door sort -n -u maar niet door de eerste! echo -e 'test \n test' | sort -n -u retourneert test, maar echo -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 aan uniq 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 ٠١٢٣ dus sort -u behoudt slechts één van elk, terwijl voor uniq (niet GNU uniq die strcoll() gebruikt (behalve met -i)), ① is anders van ② en 0123 verschillen van ٠١٢٣, dus uniq 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) terwijl strcmp() het niet kan schelen over tekens omdat het alleen byte-naar-byte-vergelijking doet. Dus dat “is nog een reden waarom sort -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 van sort geeft de eerste van een gelijke run (zie man-pagina). Dus sort -fu pikt de eerste keer op van elke niet-hoofdlettergevoelige unieke regel. De logica die sort 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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *