Mi a különbség a “ sort -u ” és a “ sort | uniq ”?

Bárhol látom, hogy valakinek válogatott, egyedi listára van szüksége, mindig a sort | uniq -hez továbbítja. Még soha nem láttam olyan példát, ahol valaki az sort -u -t használja. Miért nem? Mi a különbség, és miért jobb az uniq-et használni, mint az egyedi zászlót a rendezéshez?

Megjegyzések

Válasz

sort | uniq , és kompatibilis a rendszerek szélesebb körével, bár szinte az összes modern rendszer támogatja a -u – ez a POSIX-ot. azokra a napokra, amikor sort -u nem létezett (és az emberek nem szokták megváltoztatni a módszereiket, ha továbbra is működik az általuk ismert módszer, csak nézd meg a ifconfig és ip elfogadás).

A kettő valószínűleg összeolvadt, mert a fájlban lévő másolatok eltávolítása válogatást igényel (legalábbis a szabványban eset), és rendkívül gyakori rendezési eset. Belsőleg is gyorsabb, mivel mindkét műveletet egyszerre tudja végrehajtani (és annak a ténynek köszönhető, hogy nem szükséges IPC a uniq és iv id = között. Különösen, ha a fájl nagy, sort -u valószínűleg kevesebb köztes fájlt fog felhasználni az adatok rendezéséhez.

A rendszeremen Állandóan ilyen eredményeket kapok:

$ 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 

Nem is maszkolja a sort visszatérési kódját, amely fontos lehet (a modern héjakban vannak módok ennek megszerzésére, például bash “s $PIPESTATUS tömb, de ez nem volt” t ” mindig igaz).

megjegyzések

  • hajlamos vagyok sort | uniq -et használni, mert 10-ből 9-szer, Én ‘ igazából a uniq -c -hez vezetem.
  • Ne feledje, hogy sort -u a 7. kiadás UNIX része volt, 1979 körül. A sort verziói A -u támogatása valóban archaikus – vagy a POSIX ‘ s de jure szabvány előtt valóban a de facto szabványra lett figyelmen kívül hagyva. Lásd még: Stack Overflow Rendezés & uniq a Linux shellben 2010-től.
  • +1, mert ip. Ez ‘ 2016-ot és ezt a bejegyzést 2013-ban, de a ip parancsról csak most tudok.
  • +1 mert a ” 9-szeresére 10 I ‘ m valójában a uniq -c ” (és talán még egyszer csövezhet a sort -nr | head címre). Arra gondoltam, hogy mi felel meg a sort | uniq -nek a Vim-ben, amikor megtudtam, hogy Vim :sort u paranccsal rendelkezik. És létezik a TIL sort -u is.
  • Ne feledje, hogy a sort -n | uniq és a sort -n -u. Például a lemaradó és a vezető szóközöket a sort -n -u másolatoknak tekintik, de az előbbiek nem! A echo -e 'test \n test' | sort -n -u értéke test, de a echo -e 'test \n test' | sort -n | uniq mindkét sort visszaadja.

Válasz

Az egyik különbség az, hogy a uniq számos további hasznos lehetőséggel rendelkezik, például: mezők kihagyása összehasonlításhoz és egy érték ismétlésének számításához. A sort “s -u zászló csak a díszítés nélküli uniq parancs funkcionalitását valósítja meg.

Megjegyzések

  • +0,49 hasznos válaszért, de valami olyasmit fogalmaznék meg, hogy ” sort -u nem adható át ‘ t a uniq címre, hogy az utóbbiak egy részét felhasználhassa ‘ hasznos lehetőségek, például a mezők kihagyása az összehasonlításhoz és az ismétlések számának megszámlálása. ”
  • +1 a naysayers, mert ” ott ‘ nincs mód erre, hogy ezt közvetlenül a ” válaszol-e a kérdésre …

Válasz

POSIX-kompatibilis sort s és uniq s (a GNU uniq ebben a tekintetben jelenleg nem felel meg), van “különbség abban az értelemben, hogy sort a területi összehasonlító algoritmust használja a karaktersorozatok összehasonlításához (általában a strcoll() karakterláncokat hasonlítja össze), míg a uniq ellenőrzi a bájtérték-azonosságot (általában a következőt használja: strcmp()) ¹.

Ez legalább két okból fontos .

  • Bizonyos helyeken, különösen a GNU rendszereken, vannak különböző karakterek, amelyek ugyanazt rendezik. Például egy GNU rendszer en_US.UTF-8 területi beállításában az összes ①②③④⑤⑥⑦⑧⑨⑩ … karakter² és sok más ugyanazt rendezi, mert a rendezési sorrendjük nincs meghatározva. A 0123456789 arab számjegyek megegyeznek kelet-arab indián megfelelőikkel (٠١٢٣٤٥٦٧٨٩).

    A sort -u, the ugyanazt rendezi, mint a 0 és a 0123, mint az ٠١٢٣, így sort -u mindegyikből csak egyet tartana meg, míg a uniq (nem GNU uniq, amely a strcoll() -t használja (kivéve a -i alkalmazást)), a ① eltér ②-től és 0123-tól különbözik ٠١٢٣-től, ezért uniq mind a 4-et egyedinek tekintené.

  • strcoll csak érvényes karakterek karaktersorozatát tudja összehasonlítani (a viselkedés nincs meghatározva a POSIX szerint, ha a bemenet bájtsorozattal rendelkezik, amelyek nem formálnak érvényes karaktereket), míg a strcmp() nem törődik a karakterekről, mivel csak bájt-bájt összehasonlítást végez. Tehát ez egy másik oka annak, hogy sort -u miért nem adja meg az összes egyedi sort, ha némelyikük nem alkot érvényes szöveget. A sort|uniq ugyan nem meghatározott a nem szöveges bevitelnél, de a gyakorlatban ennélfogva nagyobb valószínűséggel ad egyedi sorokat.

Ezen finomságok mellett egy dolog, amit eddig nem vettek észre, hogy uniq az egész sort lexikailag hasonlítja össze, míg a sort “s -u összehasonlítja a parancssorban megadott rendezési specifikáció alapján.

$ 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 

¹ A POSIX specifikáció korábbi verziói azonban zavart okoztak azzal, hogy a LC_COLLATE változót felsorolták a uniq változóra, amelyet eltávolítottak a 2018-as kiadásból, és a viselkedés tisztázódott a fent említett vita nyomán. Lásd a megfelelő austini csoport hibáját

² 2019 szerkesztés . Ezeket azóta kijavították, de az Unicode kódpontok több mint 95% -a még mindig nem definiált sorrendű, a GNU libc 2.30 verziójától kezdve . Helyette tesztelheti a 🧙🧚🧛🧜🧝-val, például újabb verziókban

Válasz

Inkább használom sort | uniq mert amikor megpróbálom használni a -u (duplikátumok eltávolítása) opciót a vegyes betűs karakterláncokat tartalmazó duplikátumok eltávolítására, akkor nem olyan könnyű értsd meg az eredményt.

Megjegyzés: Mielőtt az alábbi példákat futtatnád, a következők szerint kell szimulálnod a standard C leválási sorrendet:

LC_ALL=C export LC_ALL 

Például, ha rendezni szeretnék egy fájlt, és eltávolítanám a duplikátumokat, ugyanakkor megtartanám a karakterláncok különböző eseteit.

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

Ezt a zavart úgy oldja meg, hogy nem használja az -u opciót a másolatok eltávolításához. A uniq használata kiszámíthatóbb. Az alábbiakban először rendezi és figyelmen kívül hagyja az esetet, majd továbbítja a uniq címre az ismétlések eltávolításához.

$ sort -f short | uniq Apple apple Pear pear 

Megjegyzések

  • -u sort opció adja ki a első egyenlő futásból (lásd a man oldalt). Így sort -fu felveszi minden eset-érzéketlen egyedi sor első előfordulását. Kiszámítható az a logika, amelyet sort használ a duplikátumok eltávolítására.

Válasz

Egy másik különbség, amelyet ma tapasztaltam, az, ha egy elválasztójel alapján rendezünk, ahol az sort -u az egyedi jelzőt csak arra az oszlopra alkalmazza, amellyel rendezni szeretne.

$ 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 

Megjegyzések

  • Ezt St é phane Chazelas válaszában említik, de Tetszik a példád, így +1
  • Köszönöm, hogy rámutattál a @roaima kifejezésre, ez nem volt ‘ nagyon világos ebben a válaszban.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük