Overalt hvor jeg ser nogen, der har brug for at få en sorteret, unik liste, rører de altid til sort | uniq
. Jeg har aldrig set eksempler, hvor nogen bruger sort -u
i stedet. Hvorfor ikke? Hvad er forskellen, og hvorfor er det bedre at bruge uniq end det unikke flag til at sortere?
Kommentarer
- aplawrence.com/Unixart/sort-vs-uniq.html
Svar
sort | uniq
eksisterede før sort -u
og er kompatibel med en bredere vifte af systemer, selvom næsten alle moderne systemer understøtter -u
– det er POSIX. Det er for det meste et tilbagekald til de dage, hvor sort -u
ikke eksisterede (og folk ikke har tendens til at ændre deres metoder, hvis den måde, de kender fortsætter med at arbejde, skal du bare se på ifconfig
vs. ip
adoption).
De to blev sandsynligvis flettet, fordi fjernelse af dubletter i en fil kræver sortering (i det mindste i standarden case), og er et ekstremt almindeligt brugsslag. Det er også hurtigere internt som et resultat af at være i stand til at udføre begge operationer på samme tid (og på grund af det faktum, at det ikke kræver IPC mellem uniq
og sort
). Især hvis filen er stor, vil sort -u
sandsynligvis bruge færre mellemfiler til at sortere dataene.
På mit system Jeg får konsekvent resultater som dette:
$ 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
Det maskerer heller ikke returkoden til sort
kan være vigtigt (i moderne skaller er der måder at få dette på, f.eks. bash
“s $PIPESTATUS
array, men dette var ikke t altid sandt.
Kommentarer
- Jeg plejer at bruge
sort | uniq
fordi 9 gange ud af 10, Jeg ‘ Jeg leder faktisk tiluniq -c
. - Bemærk at
sort -u
var en del af 7. udgave UNIX, omkring 1979. Versioner afsort
withou t support til-u
er virkelig arkaisk – eller blev skrevet uden opmærksomhed på de facto-standarden før POSIX ‘ s de jure-standard. Se også Stack Overflow Sorter & uniq i Linux shell fra 2010. - +1 fordi af
ip
. Det ‘ s 2016 og dette indlæg i 2013, men jeg ved kun omip
kommandoen nu. - +1 til ” 9 gange ud 10 I ‘ m rør faktisk til
uniq -c
” (og måske rør igen tilsort -nr | head
). Jeg spekulerede på, hvad der svarer tilsort | uniq
i Vim, da jeg fandt ud af, at Vim har:sort u
kommando. Og TILsort -u
findes også. - Bemærk, at der er forskel, når du bruger
sort -n | uniq
vs.sort -n -u
. For eksempel ses efterfølgende og førende hvide rum som duplikater afsort -n -u
men ikke af førstnævnte!echo -e 'test \n test' | sort -n -u
returnerertest
, menecho -e 'test \n test' | sort -n | uniq
returnerer begge linjer.
Svar
En forskel er, at uniq
har en række nyttige yderligere muligheder, såsom springer felter til sammenligning og tæller antallet af gentagelser af en værdi. sort
“s -u
flag implementerer kun funktionaliteten af den ikke-udsmykkede uniq
-kommando. p>
Kommentarer
- +0.49 for et nyttigt svar, men jeg vil sætte det i retning af ” Output af
sort -u
kan ‘ t sendes tiluniq
for at bruge nogle af sidstnævnte ‘ s nyttige indstillinger, såsom at springe over felter til sammenligning og tælle antallet af gentagelser. ” - +1 for at udligne naysayers fordi ” der ‘ ikke kan gøre dette direkte fra sortering ” besvarer spørgsmålet …
Svar
Med POSIX-kompatibel sort
s og uniq
s (GNU uniq
er i øjeblikket ikke kompatibel i den henseende), der “er en forskel ved, at sort
bruger lokalets sorteringsalgoritme til at sammenligne strenge (bruger typisk strcoll()
til at sammenligne strenge) mens uniq
kontrollerer for byteværdieidentitet (bruger typisk strcmp()
) ¹.
Det betyder noget af mindst to grunde .
-
I nogle lokaliteter, især på GNU-systemer, er der forskellige tegn, der sorterer det samme. For eksempel i en_US.UTF-8-lokaliteten på et GNU-system sorterer alle ①②③④⑤⑥⑦⑧⑨⑩ … tegn² og mange andre ens, fordi deres sorteringsrækkefølge ikke er defineret. De arabiske cifre 0123456789 sorterer det samme som deres Østlige arabiske indikatorer (٠١٢٣٤٥٦٧٨٩).
For
sort -u
, ① sorterer det samme som ② og 0123 det samme som ٠١٢٣ såsort -u
beholder kun en af hver, mens foruniq
(ikke GNUuniq
som brugerstrcoll()
(undtagen med-i
)), ① er anderledes fra ② og 0123 forskellig fra ٠١٢٣, såuniq
vil betragte alle 4 som unikke. -
strcoll
kan kun sammenligne strenge med gyldige tegn (adfærden er udefineret pr. POSIX, når input har sekvenser af bytes, der ikke danner gyldige tegn), mensstrcmp()
er ligeglad om tegn, da det kun sammenligner byte til byte. Så det er en anden grund til, atsort -u
muligvis ikke giver dig alle de unikke linjer, hvis nogle af dem ikke danner gyldig tekst.sort|uniq
, selvom det stadig er uspecificeret ved ikke-input, er det i praksis mere sandsynligt, at det giver dig unikke linjer af den grund.
Foruden disse finesser er en ting, der hidtil ikke er blevet bemærket, at uniq
sammenligner hele linjen leksikalt, mens sort
“s -u
sammenligner baseret på sorteringsspecifikationen givet på kommandolinjen.
$ 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
¹ Tidligere versioner af POSIX-specifikationen forårsagede forvirring, men ved at angive LC_COLLATE
variablen som en, der påvirker uniq
, der blev fjernet i 2018-udgaven den adfærd, der blev afklaret efter den ovennævnte diskussion. Se den tilsvarende Austin-gruppefejl
² 2019 rediger . Disse er siden blevet rettet, men over 95% af Unicode-kodepunkter har stadig en udefineret rækkefølge fra version 2.30 af GNU libc . Du kan teste med 🧙🧚🧛🧜🧝 i stedet for for eksempel i nyere versioner
Svar
Jeg foretrækker at bruge sort | uniq
fordi når jeg prøver at bruge -u
(eliminere duplikater) mulighed for at fjerne duplikater, der involverer blandede sagsstrenge, er det ikke så let at forstå resultatet.
Bemærk: Før du kan køre eksemplerne nedenfor, skal du simulere standard C-sorteringssekvensen ved at gøre følgende:
LC_ALL=C export LC_ALL
Hvis jeg f.eks. vil sortere en fil og fjerne dubletter, samtidig med at de forskellige tilfælde af strenge er forskellige.
$ 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?)
Denne forvirring løses ved ikke at bruge indstillingen -u
til at fjerne dubletter. Brug af uniq
er mere forudsigelig. Nedenstående sorterer først og ignorerer sagen og sender den derefter til uniq
for at fjerne dubletterne.
$ sort -f short | uniq Apple apple Pear pear
Kommentarer
-
-u
mulighed forsort
udsender første af en lige løb (se mand side). Såledessort -fu
opfanger den første forekomst af hver enkelt sagsfølsom unik linje. Den logik, somsort
bruger til at fjerne dubletter, er forudsigelig.
Svar
En anden forskel, jeg fandt ud af i dag, er når jeg sorterer på basis af en delimeter, hvor sort -u
kun anvender det unikke flag i den kolonne, som du sorterer med. “3c8a6f1a83”>
Kommentarer
- Dette er nævnt i et svar fra St é phane Chazelas men Jeg kan godt lide dit eksempel, så +1
- Tak fordi du påpegede @roaima, det var ikke ‘ t meget klart i det svar