{"id":83055,"date":"2020-05-28T01:42:15","date_gmt":"2020-05-27T23:42:15","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki"},"modified":"2020-05-28T01:42:15","modified_gmt":"2020-05-27T23:42:15","slug":"kak-linuxovskij-sort-sortiruet-stroki","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","title":{"rendered":"Hur sorterar Linux' sort str\u00e4ngar","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Introduktion<\/h1>\n<p><\/p>\n<p>Det hela b\u00f6rjade med ett kort skript som skulle sl\u00e5 samman information om adresser <em>e-post<\/em> fr\u00e5n anst\u00e4lldas lista i mailutskicket med anst\u00e4lldas roller fr\u00e5n personalavdelningens databas. B\u00e5da listorna exporterades till textfiler i Unicode-kodning <em>UTF-8<\/em> och sparades med Unix-radslut.<\/p>\n<p><\/p>\n<p>Inneh\u00e5ll <em>mail.txt<\/em><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ivanov Andrei;ia@example.com<\/code><\/pre>\n<p><\/p>\n<p>Inneh\u00e5ll <em>buhg.txt<\/em><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ivanova Alla;m\u00e5lare\nYelkina Ella;kranf\u00f6rare\nIvanov Andrei;svetsare\nAbakanov Mikhail;m\u00e5lare<\/code><\/pre>\n<p><\/p>\n<p>F\u00f6r att sl\u00e5 samman var filerna sorterade med Unix-kommandot <em>sort<\/em> och matades in i programmet <em>join<\/em>, som ov\u00e4ntat avslutades med ett fel: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; sort buhg.txt &gt; buhg.srt\n$&gt; sort mail.txt &gt; mail.srt\n$&gt; join buhg.srt mail.srt &gt; result\njoin: buhg.srt:4: \u00e4r inte sorterat: Ivanov Andrei;svetsare<\/code><\/pre>\n<p><\/p>\n<p>\u00d6versiktsgranskning av sorteringsresultatet visade att sorteringen \u00f6verlag var korrekt, men n\u00e4r det g\u00e4llde \u00f6verlappningar mellan manliga och kvinnliga efternamn hamnar kvinnorna f\u00f6re m\u00e4nnen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; sort buhg.txt\nAbakanov Mikhail;m\u00e5lare\nYelkina Ella;kranf\u00f6rare\nIvanova Alla;m\u00e5lare\nIvanov Andrei;svetsare<\/code><\/pre>\n<p><\/p>\n<p>Det ser ut som en bugg i Unicode-sortering eller ett uttryck f\u00f6r feminism i sorteringsalgoritmen. Det f\u00f6rsta verkar f\u00f6rst\u00e5s mer rimligt.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>L\u00e5t oss skjuta p\u00e5 det f\u00f6r nu <em>join<\/em> och fokusera p\u00e5 <em>sort<\/em>. L\u00e5t oss f\u00f6rs\u00f6ka l\u00f6sa uppgiften med trial and error. F\u00f6rst \u00e4ndrar vi locale fr\u00e5n <em>en_US<\/em> till <em>ru_RU<\/em>. F\u00f6r sortering skulle det ha r\u00e4ckt att s\u00e4tta milj\u00f6variabeln <em>LC_COLLATE<\/em>, men vi ska inte sn\u00e5la:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=ru_RU.UTF-8 sort buhg.txt\nAbakanov Mikhail;m\u00e5lare\nYelkina Ella;kranf\u00f6rare\nIvanova Alla;m\u00e5lare\nIvanov Andrei;svetsare<\/code><\/pre>\n<p><\/p>\n<p>Ingenting har f\u00f6r\u00e4ndrats.<\/p>\n<p><\/p>\n<p>L\u00e5t oss f\u00f6rs\u00f6ka konvertera filerna till en enbyteskodning: <\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; iconv -f UTF-8 -t KOI8-R buhg.txt \n | LANG=ru_RU.KOI8-R sort \n | iconv -f KOI8-R -t UTF8<\/code><\/pre>\n<p><\/p>\n<p>\u00c5terigen har ingenting f\u00f6r\u00e4ndrats.<\/p>\n<p><\/p>\n<p>Det \u00e4r ingen utv\u00e4g, vi m\u00e5ste s\u00f6ka l\u00f6sningen p\u00e5 internet. Direkt om ryska efternamn finns inget, men det finns fr\u00e5gor om andra konstigheter i sortering. Till exempel finns det ett problem: <noindex><a rel=\"nofollow\" href=\"https:\/\/serverfault.com\/questions\/95579\/unix-sort-treats-dash-characters-as-invisible\/95593\">unix sort treats &#8216;-&#8216; (dash) characters as invisible<\/a><\/noindex>. \u0415\u0441\u043b\u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438 &quot;a-b&quot;, &quot;aa&quot;, &quot;ac&quot; \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u0430\u043a &quot;aa&quot;, &quot;a-b&quot;, &quot;ac&quot;.<\/p>\n<p><\/p>\n<p>Svaren \u00e4r alltid standard: anv\u00e4nd programmerarlocale <em>&quot;C&quot;<\/em> och du f\u00e5r din lycka. Vi testar:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=C sort buhg.txt\nYelkina Ella;kranf\u00f6rare\nAbakanov Mikhail;m\u00e5lare\nIvanov Andrei;svetsare\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>N\u00e5got har f\u00f6r\u00e4ndrats. Ivanov-familjen har st\u00e4llt sig i r\u00e4tt ordning, men Jelkin har glidit bort. Vi \u00e5terg\u00e5r till den ursprungliga uppgiften:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=C sort buhg.txt &gt; buhg.srt\n$&gt; LANG=C sort mail.txt &gt; mail.srt\n$&gt; LANG=C join buhg.srt mail.srt &gt; result<\/code><\/pre>\n<p><\/p>\n<p>Det fungerade utan fel, precis som internet lovade. Och detta trots Jelkin i den f\u00f6rsta raden.<\/p>\n<p><\/p>\n<p>Problemet verkar vara l\u00f6st, men f\u00f6r s\u00e4kerhets skull provar vi en till rysk kodning \u2014 Windows-kodningen. <em>CP1251<\/em>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; iconv -f UTF-8 -t CP1251 buhg.txt \n | LANG=ru_RU.CP1251 sort \n | iconv -f CP1251 -t UTF8 <\/code><\/pre>\n<p><\/p>\n<p>Sorteringsresultatet, m\u00e4rkligt nog, kommer att \u00f6verensst\u00e4mma med lokaliteten. <em>&quot;C&quot;<\/em>, och hela exemplet g\u00e5r d\u00e4rmed igenom utan fel. Det \u00e4r n\u00e5gon slags mystik.<\/p>\n<p><\/p>\n<p>Jag gillar inte mystik i programmering, eftersom den vanligtvis d\u00f6ljer fel. Jag m\u00e5ste verkligen g\u00f6ra en djupdykning i hur det fungerar. <em>sort<\/em> och vad det p\u00e5verkar. <em>LC_COLLATE<\/em> .<\/p>\n<p><\/p>\n<p>Till slut kommer jag att f\u00f6rs\u00f6ka svara p\u00e5 fr\u00e5gorna:<\/p>\n<p><\/p>\n<ul>\n<li>varf\u00f6r kvinnliga efternamn sorterade felaktigt.<\/li>\n<li>varf\u00f6r <em>LANG=ru_RU.CP1251<\/em> visade sig vara ekvivalent. <em>LANG=C<\/em><\/li>\n<li>varf\u00f6r f\u00e5r <em>sort<\/em> och <em>join<\/em> olika representationer av ordningen f\u00f6r sorterade rader.<\/li>\n<li>varf\u00f6r finns det fel i alla mina exempel.<\/li>\n<li>slutligen, hur man sorterar rader efter eget tycke.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sortirovka-v-yunikode\">Sortering i Unicode.<\/h1>\n<p><\/p>\n<p>Den f\u00f6rsta stopppunkten kommer att vara teknisk rapport nr 10 med titeln. <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\/reports\/tr10\/\">Unicode collation algorithm.<\/a><\/noindex> p\u00e5 webbplatsen <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\">unicode.org.<\/a><\/noindex>Rapporten inneh\u00e5ller m\u00e5nga tekniska detaljer, s\u00e5 jag till\u00e5ter mig att ge en sammanfattning av huvuddiskussionerna.<\/p>\n<p><\/p>\n<p><em>Collation<\/em> \u2014 &quot;\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435&quot; \u0441\u0442\u0440\u043e\u043a \u2014 \u043e\u0441\u043d\u043e\u0432\u0430 \u043b\u044e\u0431\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438. \u0421\u0430\u043c\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f (&quot;\u043f\u0443\u0437\u044b\u0440\u044c\u043a\u043e\u043c&quot;, &quot;\u0441\u043b\u0438\u044f\u043d\u0438\u0435\u043c&quot;, &quot;\u0431\u044b\u0441\u0442\u0440\u044b\u0439&quot;), \u043d\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u044b \u0441\u0442\u0440\u043e\u043a, \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0438\u0445 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p><\/p>\n<p>Sortering av str\u00e4ngar p\u00e5 naturligt spr\u00e5k \u00e4r ett ganska komplext problem. \u00c4ven i de enklaste enbyte-kodningarna kan ordningen p\u00e5 bokst\u00e4ver i alfabetet, \u00e4ven i n\u00e5got som avviker fr\u00e5n den engelska latinska upps\u00e4ttningen, redan skilja sig fr\u00e5n den ordning av numeriska v\u00e4rden som dessa bokst\u00e4ver koden. S\u00e5 i det tyska alfabetet kommer bokstaven <em>\u00d6<\/em> att ligga mellan <em>Till<\/em> och <em>P<\/em>, men i kodningen <em>CP850<\/em> hamnar den mellan <em>\u00ff<\/em> och <em>\u00dc.<\/em>.<\/p>\n<p><\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c &quot;\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0435&quot; \u0431\u0443\u043a\u0432\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u042e\u043d\u0438\u043a\u043e\u0434\u0435. \u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438 <em>UTF8<\/em>, <em>UTF16<\/em> eller enbyte-kodning <em>KOI8-R<\/em> (om ett begr\u00e4nsat delm\u00e4ngd av Unicode beh\u00f6vs) kommer att ge olika numeriska representationer av bokst\u00e4verna, men h\u00e4nvisa till samma grundl\u00e4ggande tabell. <\/p>\n<p><\/p>\n<p>Det visar sig att \u00e4ven om vi bygger en teckentabell fr\u00e5n grunden, kommer vi inte att kunna tilldela en universell ordning f\u00f6r tecknen. I olika nationella alfabet som anv\u00e4nder samma bokst\u00e4ver kan ordningen av dessa bokst\u00e4ver skilja sig. Till exempel p\u00e5 franska <em>\u00c6<\/em> kommer att betraktas som en ligatur och sorteras som en str\u00e4ng <em>AE<\/em>. I norska spr\u00e5ket <em>\u00c6<\/em> kommer att vara en separat bokstav som ligger efter <em>Z<\/em>. F\u00f6r \u00f6vrigt, f\u00f6rutom ligaturer av typen <em>\u00c6<\/em> finns det bokst\u00e4ver som skrivs med flera tecken. S\u00e5 i det tjeckiska alfabetet finns bokstaven <em>Ch<\/em>, som ligger mellan <em>H<\/em> och <em>I<\/em>.<\/p>\n<p><\/p>\n<p>F\u00f6rutom skillnader i alfabeten finns det \u00e4ven andra nationella traditioner som p\u00e5verkar sorteringen. S\u00e4rskilt uppst\u00e5r fr\u00e5gan: i vilken ordning b\u00f6r ord best\u00e5ende av versaler och gemener f\u00f6lja i ordboken? \u00c4ven punktering kan p\u00e5verka sorteringen. P\u00e5 spanska s\u00e4tts en omv\u00e4nd fr\u00e5getecken i b\u00f6rjan av en fr\u00e5ga (<em>\u00bfTe gusta la m\u00fasica?<\/em>). I detta fall \u00e4r det uppenbart att fr\u00e5gande meningar inte b\u00f6r grupperas i en egen kluster utanf\u00f6r alfabetet, men hur b\u00f6r man sortera str\u00e4ngar med andra skiljetecken?<\/p>\n<p><\/p>\n<p>Jag kommer inte att g\u00e5 in p\u00e5 sorteringen av str\u00e4ngar i spr\u00e5k som skiljer sig kraftigt fr\u00e5n europeiska. Jag n\u00e4mner att i spr\u00e5k med skrivriktningar fr\u00e5n h\u00f6ger till v\u00e4nster eller ovanifr\u00e5n och ner, lagras tecknen i str\u00e4ngar f\u00f6rmodligen i l\u00e4sordning, och \u00e4ven i icke-alphabetiska skriftsystem finns det sina egna s\u00e4tten att ordna tecken f\u00f6r tecken. Till exempel kan hieroglyfer ordnas efter skrivs\u00e4tt (<noindex><a rel=\"nofollow\" href=\"https:\/\/studychinese.ru\/kljuchi\/\">nycklar f\u00f6r kinesiska tecken<\/a><\/noindex>) eller efter uttal. Hur emoticons b\u00f6r ordnas, kan jag \u00e4rligt talat inte f\u00f6rest\u00e4lla mig, men \u00e4ven f\u00f6r dem kan n\u00e5got utarbetas.<\/p>\n<p><\/p>\n<p>Baserat p\u00e5 ovanst\u00e5ende egenskaper har de grundl\u00e4ggande kraven f\u00f6r j\u00e4mf\u00f6relse av str\u00e4ngar baserade p\u00e5 Unicode-tabeller formulerats:<\/p>\n<p><\/p>\n<ul>\n<li>str\u00e4ngj\u00e4mf\u00f6relser \u00e4r oberoende av tecknens position i kodtabellen;<\/li>\n<li>sekvenser av tecken som bildar ett enskilt tecken omvandlas till kanonisk form (<em>A<\/em> + den \u00f6vre cirkeln \u00e4r detsamma som <em>\u00c5<\/em>);<\/li>\n<li>vid str\u00e4ngj\u00e4mf\u00f6relse betraktas tecken i kontexten av str\u00e4ngen och, om det \u00e4r n\u00f6dv\u00e4ndigt, kombineras med grannarna till en enhet f\u00f6r j\u00e4mf\u00f6relse (<em>Ch<\/em> i tjeckiska) eller delas upp i flera (<em>\u00c6<\/em> p\u00e5 franska);<\/li>\n<li>Alla nationella egenskaper (alfabet, versaler\/gemener, skiljetecken, skriftspr\u00e5kets ordning) b\u00f6r kunna anpassas, \u00e4nda ner till manuell tilldelning av ordning (emojier);<\/li>\n<li>J\u00e4mf\u00f6relse \u00e4r viktigt inte bara f\u00f6r sortering utan ocks\u00e5 p\u00e5 m\u00e5nga andra st\u00e4llen, till exempel f\u00f6r att ange radr\u00e4ckor (ers\u00e4ttning {A\u2026 \u044f} i <em>bash<\/em>);<\/li>\n<li>J\u00e4mf\u00f6relsen b\u00f6r utf\u00f6ras tillr\u00e4ckligt snabbt.<\/li>\n<\/ul>\n<p><\/p>\n<p>Dessutom har f\u00f6rfattarna till rapporten formulerat egenskaper f\u00f6r j\u00e4mf\u00f6relse som algoritmutvecklare inte b\u00f6r f\u00f6rlita sig p\u00e5:<\/p>\n<p><\/p>\n<ul>\n<li>J\u00e4mf\u00f6relsealgoritmen b\u00f6r inte kr\u00e4va en separat upps\u00e4ttning tecken f\u00f6r varje spr\u00e5k (ryska och ukrainska anv\u00e4nder gemensamt majoriteten av kyrilliska tecken);<\/li>\n<li>J\u00e4mf\u00f6relse b\u00f6r inte bygga p\u00e5 tecknens ordning i Unicode-tabeller;<\/li>\n<li>Str\u00e4ngens vikt ska inte vara en egenskap hos str\u00e4ngen, eftersom samma str\u00e4ng i olika kulturella sammanhang kan ha olika vikter;<\/li>\n<li>Vikterna f\u00f6r str\u00e4ngar kan f\u00f6r\u00e4ndras vid sammanslagning eller delning (fr\u00e5n <em>x<\/em> &lt; <em>y<\/em> Det betyder inte att <em>xz<\/em> &lt; <em>yz<\/em>);<\/li>\n<li>Olika str\u00e4ngar som har samma vikt betraktas som lika fr\u00e5n algoritmens sorteringssynpunkt. Att inf\u00f6ra ytterligare ordning f\u00f6r s\u00e5dana str\u00e4ngar \u00e4r m\u00f6jligt, men det kan f\u00f6rs\u00e4mra prestandan;<\/li>\n<li>Vid upprepade sorteringar kan str\u00e4ngar med samma vikt byta plats. Stabilitet \u00e4r en egenskap hos en specifik sorteringsalgoritm, inte en egenskap hos en str\u00e4ngj\u00e4mf\u00f6relsealgoritm (se f\u00f6reg\u00e5ende punkt);<\/li>\n<li>Sorteringsregler kan f\u00f6r\u00e4ndras \u00f6ver tid i takt med att kulturella traditioner f\u00f6rtydligas\/f\u00f6r\u00e4ndras.<\/li>\n<\/ul>\n<p><\/p>\n<p>Det konstateras ocks\u00e5 att j\u00e4mf\u00f6relsealgoritmen inte k\u00e4nner till semantiken hos de bearbetade str\u00e4ngarna. S\u00e5, str\u00e4ngar som endast best\u00e5r av siffror b\u00f6r inte j\u00e4mf\u00f6ras som tal, och i listor \u00f6ver engelska namn b\u00f6r artikeln inte tas bort (<em>Beatles, The<\/em>).<\/p>\n<p><\/p>\n<p>F\u00f6r att uppfylla alla angivna krav f\u00f6resl\u00e5s en flerniv\u00e5 (faktiskt fyrniv\u00e5) tabellsorteringsalgoritm.<\/p>\n<p><\/p>\n<p>I f\u00f6rv\u00e4g omvandlas tecknen i str\u00e4ngen till kanonisk form och grupperas i j\u00e4mf\u00f6relseenheter. Varje j\u00e4mf\u00f6relseenhet tilldelas flera vikter som motsvarar flera niv\u00e5er av j\u00e4mf\u00f6relse. Vikterna f\u00f6r j\u00e4mf\u00f6relseenheterna \u00e4r element i ordnade m\u00e4ngder (i detta fall heltal) som kan j\u00e4mf\u00f6ras som st\u00f6rre eller mindre. Speciellt v\u00e4rde <em>IGNORED<\/em> (0x0) inneb\u00e4r att enheten i fr\u00e5ga inte deltar i j\u00e4mf\u00f6relsen p\u00e5 den aktuella niv\u00e5 som j\u00e4mf\u00f6rs. Str\u00e4ngj\u00e4mf\u00f6relser kan upprepas flera g\u00e5nger med hj\u00e4lp av vikter f\u00f6r de aktuella niv\u00e5erna. Vid varje niv\u00e5 j\u00e4mf\u00f6rs vikterna f\u00f6r j\u00e4mf\u00f6relseenheterna i de tv\u00e5 str\u00e4ngarna med varandra.<\/p>\n<p><\/p>\n<p>I olika implementationer av algoritmen f\u00f6r olika nationella traditioner kan koefficientv\u00e4rdena skilja sig, men standarden Unicode inneh\u00e5ller en grundl\u00e4ggande vikt-tabell \u2014 <em>&quot;Default Unicode Collation Element Table&quot;<\/em> (<em>DUCET<\/em>). Jag vill p\u00e5peka att installationen av variabeln <em>LC_COLLATE<\/em> faktiskt \u00e4r en indikation p\u00e5 valet av vikt-tabellen i str\u00e4ngj\u00e4mf\u00f6relsefunktionen.<\/p>\n<p><\/p>\n<p>Viktkoefficienterna <em>DUCET<\/em> \u00e4r ordnade p\u00e5 f\u00f6ljande s\u00e4tt:<\/p>\n<p><\/p>\n<ul>\n<li>p\u00e5 f\u00f6rsta niv\u00e5n konverteras alla bokst\u00e4ver till samma fall, diakritiska tecken avvisas, och skiljetecken (inte alla) ignoreras;<\/li>\n<li>p\u00e5 andra niv\u00e5n beaktas endast diakritiska tecken;<\/li>\n<li>p\u00e5 tredje niv\u00e5n beaktas endast fallet;<\/li>\n<li>p\u00e5 fj\u00e4rde niv\u00e5n beaktas endast skiljetecken.<\/li>\n<\/ul>\n<p><\/p>\n<p>J\u00e4mf\u00f6relsen sker i flera genomg\u00e5ngar: f\u00f6rst j\u00e4mf\u00f6rs koefficienterna p\u00e5 f\u00f6rsta niv\u00e5n; om vikterna st\u00e4mmer \u00f6verens, sker en upprepning av j\u00e4mf\u00f6relsen med vikterna p\u00e5 andra niv\u00e5n; f\u00f6ljt av kanske tredje och fj\u00e4rde.<\/p>\n<p><\/p>\n<p>J\u00e4mf\u00f6relsen avslutas n\u00e4r det finns motsvarande j\u00e4mf\u00f6relseenheter med olika vikter i str\u00e4ngerna. Str\u00e4ngar med lika vikter p\u00e5 alla fyra niv\u00e5erna anses vara lika.<\/p>\n<p><\/p>\n<p>Denna algoritm (med massor av ytterligare tekniska detaljer) gav namn \u00e5t rapport nr 10 \u2014 <em>&quot;Unicode Collation Algorithm&quot;<\/em> (<em>UCA<\/em>).<\/p>\n<p><\/p>\n<p>Vid denna punkt blir sorteringsbeteendet i v\u00e5rt exempel n\u00e5got mer begripligt. Det vore bra att j\u00e4mf\u00f6ra det med standarden Unicode.<\/p>\n<p><\/p>\n<p>F\u00f6r att testa implementationerna <em>UCA<\/em> finns det ett speciellt <noindex><a rel=\"nofollow\" href=\"https:\/\/www.unicode.org\/Public\/UCA\/latest\/CollationTest.html\">test<\/a><\/noindex>, som anv\u00e4nder <noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">en vikt-fil<\/a><\/noindex>, implementerar <em>DUCET<\/em>. I vikt-filen kan man hitta olika roliga detaljer. Till exempel finns d\u00e4r ordningen f\u00f6r mahjongbrickor och europeiskt domino, samt ordningen f\u00f6r f\u00e4rger i en kortlek (symbol <em>1F000<\/em> och s\u00e5 vidare). Kortf\u00e4rgerna \u00e4r placerade enligt bridge-reglerna \u2014 PCHBT, och korten i varje f\u00e4rg \u2014 i ordningen T,2,3\u2026 K.<\/p>\n<p><\/p>\n<p>Manuell kontroll av korrektheten i sorteringen av str\u00e4ngar enligt <em>DUCET<\/em> \u0431\u044b\u043b\u0430 \u0431\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439, \u043d\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u043d\u0430\u0441, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0437\u0446\u043e\u0432\u043e-\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u042e\u043d\u0438\u043a\u043e\u0434\u043e\u043c \u2014 &quot;<noindex><a rel=\"nofollow\" href=\"http:\/\/site.icu-project.org\/\">International Components for Unicode<\/a><\/noindex>&quot; (<em>ICU<\/em>).<\/p>\n<p><\/p>\n<p>P\u00e5 webbplatsen f\u00f6r detta bibliotek, utvecklat av <em>IBM<\/em>, finns demonstrationssidor, inklusive <noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">sidan f\u00f6r str\u00e4ngj\u00e4mf\u00f6relsealgoritmen<\/a><\/noindex>. Vi matar in v\u00e5ra teststr\u00e4ngar med standardinst\u00e4llningar och, \u00e5h under, f\u00e5r en perfekt rysk sortering.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Abakanov Michail;m\u00e5lare\nJolkina Ella;kranf\u00f6rare\nIvanov Andrej;svetsare\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>F\u00f6rresten, p\u00e5 webbplatsen <em>ICU<\/em> kan man hitta en f\u00f6rtydligande av hur algoritmen f\u00f6r j\u00e4mf\u00f6relse fungerar vid hantering av skiljetecken. I exempel <noindex><a rel=\"nofollow\" href=\"http:\/\/userguide.icu-project.org\/collation\/faq\">Collation FAQ<\/a><\/noindex> ignoreras apostrof och bindestreck.<\/p>\n<p><\/p>\n<p>Unicode hj\u00e4lpte oss, men att leta efter orsakerna till det konstiga beteendet <em>sort<\/em> p\u00e5 <em>Linux<\/em> kommer vi att beh\u00f6va g\u00f6ra n\u00e5gon annanstans.<\/p>\n<p><\/p>\n<h1 id=\"sortirovka-v-glibc\">Sortering i glibc<\/h1>\n<p><\/p>\n<p>En snabb titt p\u00e5 k\u00e4llkoderna f\u00f6r verktyget <em>sort<\/em> fr\u00e5n <em>GNU Core Utils<\/em> visade att lokalisering i sj\u00e4lva verktyget handlar om att skriva ut det nuvarande v\u00e4rdet av variabeln <em>LC_COLLATE<\/em> vid k\u00f6rning i fels\u00f6kningsl\u00e4ge:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ sort --debug buhg.txt &gt; buhg.srt\nsort: anv\u00e4nder 'en_US.UTF8' sorteringsregler<\/code><\/pre>\n<p><\/p>\n<p>Str\u00e4ngj\u00e4mf\u00f6relse g\u00f6rs av den standardiserade funktionen <em>strcoll<\/em>, vilket inneb\u00e4r att allt intressant finns i biblioteket <em>glibc<\/em>.<\/p>\n<p><\/p>\n<p>P\u00e5 <em>wiki<\/em> projektet <em>glibc<\/em> str\u00e4ngj\u00e4mf\u00f6relse \u00e4gnas <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/glibc\/wiki\/Locales#LC_COLLATE\">ett stycke<\/a><\/noindex>. Av detta stycke kan man f\u00f6rst\u00e5 att i <em>glibc<\/em> sorteringen baseras p\u00e5 den redan k\u00e4nda algoritmen <em>UCA<\/em> (<em>The Unicode collation algorithm<\/em>) och\/eller den n\u00e4rst\u00e5ende standarden <em>ISO 14651<\/em> (<em>Internationell str\u00e4ngordning och -j\u00e4mf\u00f6relse<\/em>). Ang\u00e5ende den senaste standarden b\u00f6r n\u00e4mnas att den p\u00e5 webbplatsen <noindex><a rel=\"nofollow\" href=\"https:\/\/standards.iso.org\/ittf\/PubliclyAvailableStandards\">standards.iso.org<\/a><\/noindex> <em>ISO 14651<\/em> officiellt har utlysts offentlig, men den tillh\u00f6rande l\u00e4nken leder till en icke-existerande sida. Google visar flera sidor med l\u00e4nkar till officiella webbplatser som erbjuder att k\u00f6pa en elektronisk kopia av standarden f\u00f6r hundra euro, men p\u00e5 den tredje-fj\u00e4rde sidan av s\u00f6kresultatet finns \u00e4ven direkta l\u00e4nkar till <em>PDF<\/em>. \u00d6ver lag skiljer sig standarden praktiskt taget inte fr\u00e5n <em>UCA<\/em>, men den \u00e4r tr\u00e5kigare att l\u00e4sa eftersom den inte inneh\u00e5ller tydliga exempel p\u00e5 nationella s\u00e4rdrag i str\u00e4ngsortering. <\/p>\n<p><\/p>\n<p>Den mest intressanta informationen p\u00e5 <em>wiki<\/em> var en l\u00e4nk till <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=14095\">buggrapporten<\/a><\/noindex> som diskuterar implementeringen av str\u00e4ngj\u00e4mf\u00f6relse i <em>glibc<\/em>. Fr\u00e5n diskussionen kan man f\u00f6rst\u00e5 att i <em>glibc<\/em> f\u00f6r str\u00e4ngj\u00e4mf\u00f6relse anv\u00e4nds <em>ISO<\/em>ett tabellformat <noindex><a rel=\"nofollow\" href=\"http:\/\/www.iso.org\/ittf\/ISO14651_2006_TABLE1_en.txt\">The Common Template Table<\/a><\/noindex> (<em>CTT<\/em>), vars adress kan hittas i bilagan <em>A<\/em> till standarden <em>ISO 14651<\/em>. Mellan 2000 och 2015 var denna tabell i <em>glibc<\/em> hade ingen f\u00f6rvaltare och skilde sig ganska mycket (\u00e5tminstone utseendem\u00e4ssigt) fr\u00e5n den aktuella standardversionen. Fr\u00e5n 2015 till 2018 genomgick den anpassning till den nya tabellen och just nu har du en chans att m\u00f6ta b\u00e5de den nya tabellen (<em>CentOS 8<\/em>), samt den gamla (<em>CentOS 7<\/em>). <\/p>\n<p><\/p>\n<p>Nu n\u00e4r vi har all information om algoritmen och hj\u00e4lp-tabellerna kan vi \u00e5terv\u00e4nda till det ursprungliga problemet och f\u00f6rst\u00e5 hur man korrekt sorterar str\u00e4ngar i rysk lokal.<\/p>\n<p><\/p>\n<h1 id=\"iso-1465114652\">ISO 14651\/14652<\/h1>\n<p><\/p>\n<p>K\u00e4llkoden f\u00f6r den tabell vi \u00e4r intresserade av <em>CTT<\/em> finns i de flesta distributioner <em>Linux<\/em> i katalogen <em>\/usr\/share\/i18n\/locales\/<\/em>. Sj\u00e4lva tabellen finns i filen <em>iso14651_t1_common<\/em>. Sedan inkluderas denna fil med direktivet <em>copy iso14651_t1_common<\/em> i filen <em>iso14651_t1<\/em>, som i sin tur inkluderas i nationella filer, inklusive <em>en_US<\/em> och <em>ru_RU<\/em>. I de flesta distributioner <em>Linux<\/em> ing\u00e5r alla k\u00e4llfiler i den grundl\u00e4ggande installationen, men om de inte finns, m\u00e5ste du installera ett extra paket fr\u00e5n distributionen.<\/p>\n<p><\/p>\n<p>Strukturen p\u00e5 filen <em>iso14651_t1<\/em> kan tyckas vara fruktansv\u00e4rt ordig, med oklara regler f\u00f6r namnens uppbyggnad, men om man begriper sig p\u00e5 det \u00e4r allt ganska enkelt. Strukturen beskrivs i standarden <em>ISO 14652<\/em>, en kopia av vilken kan laddas ner fr\u00e5n sidan <noindex><a rel=\"nofollow\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG20\/docs\/n972-14652ft.pdf\">open-std.org<\/a><\/noindex>. En annan beskrivning av filformatet kan l\u00e4sas i <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/basedefs\/V1_chap07.html\">specifikationerna<\/a><\/noindex> <em>POSIX<\/em> fr\u00e5n <em>OpenGroup<\/em>. Som ett alternativ till att l\u00e4sa standarden kan man studera k\u00e4llkoden f\u00f6r funktionen <em>collate_read<\/em> p\u00e5 <em>glibc\/locale\/programs\/ld-collate.c<\/em>.<\/p>\n<p><\/p>\n<p>Filens struktur ser ut som f\u00f6ljer:<\/p>\n<p><\/p>\n<p>Som standard anv\u00e4nds symbolen som en escape-symbol, och slutet av en rad efter symbolen # \u00e4r en kommentar. B\u00e5da symbolerna kan \u00e5sidos\u00e4ttas, vilket har gjorts i den nya versionen av tabellen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">escape_char \/\ncomment_char %<\/code><\/pre>\n<p><\/p>\n<p>I filen f\u00f6rekommer det token i formatet <em>&lt;Uxxxx&gt;<\/em> eller <em>&lt;Uxxxxxxxx&gt;<\/em> (d\u00e4r <em>x<\/em> \u2014 \u00e4r en hexadecimalt siffra). Detta \u00e4r den hexadecimala representationen av Unicode-kodpunkter i kodningen <em>UCS-4<\/em> (<em>UTF-32<\/em>). Alla andra element i vinkelparenteser (inklusive <em>&lt;Uxxxx_xxxx&gt;<\/em>, <em>&lt;2&gt;<\/em> och liknande), betraktas som vanliga str\u00e4ngkonstanter som saknar s\u00e4rskild betydelse utanf\u00f6r kontext.<\/p>\n<p><\/p>\n<p>Str\u00e4ng <em>LC_COLLATE<\/em> ber\u00e4ttar f\u00f6r oss att datan som beskriver str\u00e4ngj\u00e4mf\u00f6relserna b\u00f6rjar h\u00e4r.<\/p>\n<p><\/p>\n<p>F\u00f6rst anges namn f\u00f6r vikterna i j\u00e4mf\u00f6relse tabellen och namn f\u00f6r kombinationerna av tecken. Generellt tillh\u00f6r de tv\u00e5 namntyperna tv\u00e5 olika entiteter, men i den verkliga filen \u00e4r de blandade. Namnen p\u00e5 vikterna anges med nyckelordet <em>sorteringssymbol<\/em> (sorteringssymbol), eftersom Unicode-symboler med samma vikt kommer att betraktas som j\u00e4mf\u00f6rbara symboler.<\/p>\n<p><\/p>\n<p>Den totala l\u00e4ngden p\u00e5 sektionen i den nuvarande versionen av filen \u00e4r cirka 900 rader. Jag har tagit exempel fr\u00e5n flera st\u00e4llen f\u00f6r att visa slumpm\u00e4ssigheten i namnen och n\u00e5gra typer av syntax.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">LC_COLLATE\n\ncollating-symbol &lt;RES-1&gt;\ncollating-symbol &lt;BLK&gt;\ncollating-symbol &lt;MIN&gt;\ncollating-symbol &lt;WIDE&gt;\n...\ncollating-symbol &lt;ARABIC&gt;\ncollating-symbol &lt;ETHPC&gt;\ncollating-symbol &lt;OSMANYA&gt;\n...\ncollating-symbol &lt;S1D000&gt;..&lt;S1D35F&gt;\ncollating-symbol &lt;SFFFF&gt; % Guaranteed largest symbol value. Keep at end of this list\n...\ncollating-element &lt;U0413_0301&gt; from &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;\ncollating-element &lt;U0413_0341&gt; from &quot;&lt;U0413&gt;&lt;U0341&gt;&quot;<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><em>sorteringssymbol<\/em> registrerar str\u00e4ng <em>OSMANYA<\/em> i viktens namn tabell <\/li>\n<li><em>sorteringssymbol ..<\/em> registrerar en sekvens av namn som best\u00e5r av ett prefix <em>S<\/em> och ett hexadecimalt nummer suffix fr\u00e5n <em>1D000<\/em> till <em>1D35F<\/em>.<\/li>\n<li><em>FFFF<\/em> p\u00e5 <em>sorteringssymbol<\/em> ser ut som ett stort osignerat heltal i hexadecimalt format, men <em>&lt;SFFFF&gt;<\/em> \u00e4r bara ett namn som skulle kunna se ut som <em>&lt;VERYBIGVAL&gt;<\/em> <\/li>\n<li>namn <em>&lt;U0413&gt;<\/em> betyder kodpunkt i kodningen <em>UCS-4<\/em><\/li>\n<li><em>collating-element &lt;U0413_0301&gt; from &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;<\/em> registrerar ett nytt namn f\u00f6r paret av Unicode-punkter. <\/li>\n<\/ul>\n<p><\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u043c\u0435\u043d\u0430 \u0432\u0435\u0441\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0441\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u0440\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435-\u043c\u0435\u043d\u044c\u0448\u0435, \u0442\u043e \u0432\u0435\u0441\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438\u043c\u0451\u043d. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 &quot;\u043b\u0451\u0433\u043a\u0438\u0435&quot; \u0432\u0435\u0441\u0430, \u0437\u0430\u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 &quot;\u0442\u044f\u0436\u0451\u043b\u044b\u0435&quot;. \u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044e\u043d\u0438\u043a\u043e\u0434\u043e\u0432\u0441\u043a\u043e\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0442\u044b\u0440\u0435 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0435\u0441\u0430. \u0417\u0434\u0435\u0441\u044c \u043e\u043d\u0438 \u0441\u0432\u0435\u0434\u0435\u043d\u044b \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043b\u044e\u0431\u043e\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0438\u043c\u044f \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439, \u043d\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442 \u0438\u043c\u0435\u043d\u0430 \u043f\u043e \u0443\u0440\u043e\u0432\u043d\u044f\u043c.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">% Symboliska viktf\u00f6rdelningar\n\n% Tredje niv\u00e5 viktf\u00f6rdelningar\n\n\n\n\n...\n% Andra niv\u00e5 viktf\u00f6rdelningar\n\n % KOMBINERANDE L\u00c5G LINJE\n % KOMBINERANDE KOMMA OCH \u00d6VER\n % KOMBINERANDE \u00c5TERV\u00c4ND KOMMA OCH \u00d6VER\n...\n% F\u00f6rsta niv\u00e5 viktf\u00f6rdelningar\n % HORIZONTAL TABULATION\n % LINJEBREAK\n % VERTIKAL TABULERING\n...\n % CYRILLIC LITTLE LETTER DE\n % CYRILLIC LITTLE LETTER KOMI DE\n % CYRILLIC LITTLE LETTER DJE\n % CYRILLIC LITTLE LETTER KOMI DJE\n % CYRILLIC LITTLE LETTER GJE\n % CYRILLIC LITTLE LETTER ZE WITH DESCENDER\n % CYRILLIC LITTLE LETTER IE\n % CYRILLIC LITTLE LETTER IE WITH BREVE\n % CYRILLIC LITTLE LETTER UKRAINIAN IE\n % CYRILLIC LITTLE LETTER ZHE<\/code><\/pre>\n<p><\/p>\n<p>Slutligen, sj\u00e4lva vikt-tabellen.<\/p>\n<p><\/p>\n<p>Viktsektionen \u00e4r innesluten i rader med nyckelord <em>order_start<\/em> och <em>order_end<\/em>. Ytterligare parametrar <em>order_start<\/em> best\u00e4mmer i vilken riktning raderna visas p\u00e5 varje j\u00e4mf\u00f6relse niv\u00e5. Som standard anv\u00e4nds parametern <em>fram\u00e5t<\/em>. Kroppen av sektionen best\u00e5r av rader som inneh\u00e5ller teckenkod och fyra av dess vikter. Teckenkoden kan representeras av sj\u00e4lva tecknet, kodpunkten eller det symboliska namnet som definierats tidigare. Vikterna kan ocks\u00e5 anges med symboliska namn, kodpunkter eller sj\u00e4lva tecknen. Om kodpunkter eller tecken anv\u00e4nds, kommer deras vikt att motsvara det numeriska v\u00e4rdet av kodpunkten (positionen i Unicode-tabellen). Tecken som inte anges tydligt (s\u00e5vitt jag f\u00f6rst\u00e5r) anses tilldelade i tabellen med en prim\u00e4r vikt motsvarande positionen i Unicode-tabellen. Det speciella viktv\u00e4rdet <em>IGNORE<\/em> betyder att detta tecken ignoreras p\u00e5 den aktuella j\u00e4mf\u00f6relseniv\u00e5n.<\/p>\n<p><\/p>\n<p>F\u00f6r att demonstrera vikternas struktur har jag valt tre ganska uppenbara fragment:<\/p>\n<p><\/p>\n<ul>\n<li>tecken som helt ignoreras<\/li>\n<li>tecken som \u00e4r likv\u00e4rdiga med siffran tre p\u00e5 de f\u00f6rsta tv\u00e5 niv\u00e5erna<\/li>\n<li>b\u00f6rjan av det kyrilliska alfabetet, som inte inneh\u00e5ller diakritiska tecken, och d\u00e4rf\u00f6r sorteras fr\u00e4mst efter f\u00f6rsta och tredje niv\u00e5erna.<\/li>\n<\/ul>\n<p><\/p>\n<pre><code class=\"plaintext\">order_start forward;forward;forward;forward,position\n IGNORE;IGNORE;IGNORE;IGNORE % NULL (in 6429)\n IGNORE;IGNORE;IGNORE;IGNORE % START OF HEADING (in 6429)\n IGNORE;IGNORE;IGNORE;IGNORE % START OF TEXT (in 6429)\n...\n ;;; % DIGIT THREE\n ;;; % FULLWIDTH DIGIT THREE\n ;;; % PARENTHESIZED DIGIT THREE\n ;;; % DIGIT THREE FULL STOP\n ;;<FONT>; % MATHEMATICAL BOLD DIGIT THREE\n...\n ;;; % CYRILLIC SMALL LETTER A\n ;;; % CYRILLIC CAPITAL LETTER A\n ;;; % CYRILLIC SMALL LETTER A WITH BREVE\n ;;; % CYRILLIC SMALL LETTER A WITH BREVE\n...\n ;;; % CYRILLIC SMALL LETTER BE\n ;;; % CYRILLIC CAPITAL LETTER BE\n ;;; % CYRILLIC SMALL LETTER VE\n ;;; % CYRILLIC CAPITAL LETTER VE\n...\norder_end<\/code><\/pre>\n<p><\/p>\n<p>Nu kan vi \u00e5terg\u00e5 till sorteringen av exemplen fr\u00e5n b\u00f6rjan av artikeln. F\u00e4llan ligger just i denna del av vikt-tabellen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">IGNORE;IGNORE;IGNORE; % SPACE\n IGNORE;IGNORE;IGNORE; % EXCLAMATION MARK\n IGNORE;IGNORE;IGNORE; % QUOTATION MARK\n...<\/code><\/pre>\n<p><\/p>\n<p>Det \u00e4r tydligt att i denna tabell \u00e4r interpunktionst\u00e4llen fr\u00e5n tabellen <em>ASCII<\/em> (inklusive mellanslag) vid j\u00e4mf\u00f6relse av str\u00e4ngar n\u00e4stan alltid ignoreras. Undantaget utg\u00f6rs av str\u00e4ngar som \u00f6verensst\u00e4mmer helt, f\u00f6rutom interpunktion som f\u00f6rekommer p\u00e5 matchande positioner. Str\u00e4ngarna i mitt exempel (efter sortering) ser ut s\u00e5 h\u00e4r f\u00f6r j\u00e4mf\u00f6relsealgoritmen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">AbakanovMihailm\u00e5lare\nJolkinaEllaKransk\u00e4r\nIvanovaAllaM\u00e5lare\nIvanovAndreiSmed<\/code><\/pre>\n<p><\/p>\n<p>Med tanke p\u00e5 att stora bokst\u00e4ver i ryska spr\u00e5ket i vikt-tabellen kommer efter sm\u00e5 bokst\u00e4ver (p\u00e5 tredje niv\u00e5n <em>&lt;CAP&gt;<\/em> tyngre \u00e4n <em>&lt;MIN&gt;<\/em>), ser sorteringen helt korrekt ut.<\/p>\n<p><\/p>\n<p>Vid inst\u00e4lld variabel <em>LC_COLLATE=C<\/em> laddas en s\u00e4rskild tabell som anger byte-f\u00f6r-byte j\u00e4mf\u00f6relse<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">static const uint32_t collseqwc[] =\n{\n  8, 1, 8, 0x0, 0xff,\n  \\\/ * 1st-level table *\\\n  6 * sizeof (uint32_t),\n  \\\/ * 2nd-level table *\\\n  7 * sizeof (uint32_t),\n  \\\/ * 3rd-level table *\\\n  L'x00', L'x01', L'x02', L'x03', L'x04', L'x05', L'x06', L'x07',\n  L'x08', L'x09', L'x0a', L'x0b', L'x0c', L'x0d', L'x0e', L'x0f',\n\n...\n  L'xf8', L'xf9', L'xfa', L'xfb', L'xfc', L'xfd', L'fe', L'xff'\n};<\/code><\/pre>\n<p><\/p>\n<p>Eftersom kodpunkten \u0401 i Unicode st\u00e5r f\u00f6re A, sorteras str\u00e4ngarna d\u00e4refter.<\/p>\n<p><\/p>\n<h1 id=\"tekstovye-i-dvoichnye-tablicy\">Text- och bin\u00e4ra tabeller<\/h1>\n<p><\/p>\n<p>Det \u00e4r uppenbart att str\u00e4ngj\u00e4mf\u00f6relse \u00e4r en mycket vanlig operation, medan tolkning av tabellen <em>CTT<\/em> \u00e4r en relativt kostsam procedur. F\u00f6r att optimera \u00e5tkomsten till tabellen kompileras den till bin\u00e4r form av kommandot <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Team <em>localedef<\/em> tar emot som parametrar en fil med nationella s\u00e4rdrag (alternativ <em>-i<\/em>), d\u00e4r alla tecken representeras av Unicode-punkter, och en fil med \u00f6verensst\u00e4mmelse mellan Unicode-punkter och tecken i en specifik kodning (alternativ <em>-f<\/em>). Som resultat av processen skapas bin\u00e4rfiler f\u00f6r lokalinst\u00e4llningen, namnet som anges i den sista parametern.<\/p>\n<p><\/p>\n<p><em>Glibc<\/em> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0432\u0430 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432: &quot;\u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439&quot; \u0438 &quot;\u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439&quot;.<\/p>\n<p><\/p>\n<p>Det traditionella formatet inneb\u00e4r att lokalinst\u00e4llningens namn \u00e4r namnet p\u00e5 underkatalogen i <em>\/usr\/lib\/locale\/<\/em>. I denna underkatalog lagras bin\u00e4rfiler <em>LC_COLLATE<\/em>, <em>LC_CTYPE<\/em>, <em>LC_TIME<\/em> och s\u00e5 vidare. Filen <em>LC_IDENTIFICATION<\/em> inneh\u00e5ller det formella namnet p\u00e5 lokalinst\u00e4llningen (som kan skilja sig fr\u00e5n katalognamnet) och kommentarer.<\/p>\n<p><\/p>\n<p>Det moderna formatet f\u00f6ruts\u00e4tter att alla lokalinst\u00e4llningar lagras i ett enda arkiv <em>\/usr\/lib\/locale\/locale-archive<\/em>, vilket avbildas i det virtuella minnet f\u00f6r alla processer som anv\u00e4nder <em>glibc<\/em>. Namnet p\u00e5 lokal i modern form genomg\u00e5r viss kanonisering \u2013 endast siffror och bokst\u00e4ver i sm\u00e5 bokst\u00e4ver kvarst\u00e5r i kodningens namn. S\u00e5 <em>ru_RU.KOI8-R<\/em>, sparas som <em>ru_RU.koi8r<\/em>.<\/p>\n<p><\/p>\n<p>Ing\u00e5ngsfiler s\u00f6ks i den aktuella katalogen, samt i kataloger <em>\/usr\/share\/i18n\/locales\/<\/em> och <em>\/usr\/share\/i18n\/charmaps\/<\/em> f\u00f6r filer <em>CTT<\/em> och kodningsfiler respektive.<\/p>\n<p><\/p>\n<p>Till exempel, kommandot<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">localedef -i ru_RU -f MAC-CYRILLIC ru_RU.MAC-CYRILLIC<\/code><\/pre>\n<p><\/p>\n<p>kompilerar filen <em>\/usr\/share\/i18n\/locales\/ru_RU<\/em> med hj\u00e4lp av kodningsfilen <em>\/usr\/share\/i18n\/charmaps\/MAC-CYRILLIC.gz<\/em> och sparar resultatet i <em>\/usr\/lib\/locale\/locale-archive<\/em> under namnet <em>ru_RU.maccyrillic<\/em><\/p>\n<p><\/p>\n<p>Om du s\u00e4tter variabeln <em>LANG=en_US.UTF-8<\/em> d\u00e5 <em>glibc<\/em> kommer den att leta efter bin\u00e4rfiler f\u00f6r lokal i f\u00f6ljande ordning av filer och kataloger:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">\/usr\/lib\/locale\/locale-archive\n\/usr\/lib\/locale\/en_US.UTF-8\/\n\/usr\/lib\/locale\/en_US\/\n\/usr\/lib\/locale\/enUTF-8\/\n\/usr\/lib\/locale\/en\/<\/code><\/pre>\n<p><\/p>\n<p>Om en lokal f\u00f6rekommer b\u00e5de i traditionell och modern form, ges prioritet till den moderna.<\/p>\n<p><\/p>\n<p>F\u00f6r att visa listan \u00f6ver kompilerade lokaler kan kommandot <em>locale -a<\/em>.<\/p>\n<p><\/p>\n<h1 id=\"podgotovka-svoey-tablicy-sravneniya\">F\u00f6rbereda sin egen sorteringstabell<\/h1>\n<p><\/p>\n<p>Nu, bev\u00e4pnad med kunskap, kan du skapa din egen perfekta sorteringstabell f\u00f6r str\u00e4ngar. Denna tabell ska korrekt j\u00e4mf\u00f6ra ryska bokst\u00e4ver, inklusive bokstaven \u0401, och ta h\u00e4nsyn till skiljetecken enligt tabellen <em>ASCII<\/em>.<\/p>\n<p><\/p>\n<p>Processen f\u00f6r att f\u00f6rbereda sin egen sorteringstabell best\u00e5r av tv\u00e5 steg: redigering av vikt-tabellen och kompilerande av den i bin\u00e4r form med kommandot <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>F\u00f6r att justera sorteringstabellen med minimal redigeringskostnad, finns det sektioner f\u00f6r justering av vikter i det befintliga formatet. <em>ISO 14652<\/em> Sektionen b\u00f6rjar med nyckelordet <em>reorder-after<\/em> och anvisningen av positionen, efter vilken ers\u00e4ttningen g\u00f6rs. Sektionen avslutas med raden <em>reorder-end<\/em>. Om du beh\u00f6ver justera flera avsnitt av tabellen, skapas en sektion f\u00f6r varje s\u00e5dant avsnitt.<\/p>\n<p><\/p>\n<p>Jag kopierade nya versioner av filerna <em>iso14651_t1_common<\/em> och <em>ru_RU<\/em> fr\u00e5n arkivet <em>glibc<\/em> till min hemkatalog ~\\\/ .local\\\/share\\\/i18n\\\/locales\\\/ och gjorde n\u00e5gra sm\u00e5 \u00e4ndringar i avsnittet <em>LC_COLLATE<\/em> p\u00e5 <em>ru_RU<\/em>. De nya versionerna av filerna \u00e4r helt kompatibla med min version <em>glibc<\/em>. Om du vill anv\u00e4nda \u00e4ldre versioner av filer, m\u00e5ste du \u00e4ndra de symboliska namnen och den plats d\u00e4r ers\u00e4ttningen b\u00f6rjar i tabellen.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">LC_COLLATE\n% Copy the template from ISO\/IEC 14651\ncopy &quot;iso14651_t1&quot;\nreorder-after &lt;U000D&gt;\n&lt;U0020&gt; &lt;S0020&gt;;&lt;BASE&gt;;&lt;MIN&gt;;&lt;U0020&gt; % SPACE\n&lt;U0021&gt; &lt;S0021&gt;;&lt;BASE&gt;;&lt;MIN&gt;;&lt;U0021&gt; % EXCLAMATION MARK\n&lt;U0022&gt; &lt;S0022&gt;;&lt;BASE&gt;;&lt;MIN&gt;;&lt;U0022&gt; % QUOTATION MARK\n...\n&lt;U007D&gt; &lt;S007D&gt;;&lt;BASE&gt;;&lt;MIN&gt;;&lt;U007D&gt; % RIGHT CURLY BRACKET\n&lt;U007E&gt; &lt;S007E&gt;;&lt;BASE&gt;;&lt;MIN&gt;;&lt;U007E&gt; % TILDE\nreorder-end\nEND LC_COLLATE<\/code><\/pre>\n<p><\/p>\n<p>Faktiskt borde jag ha bytt ut f\u00e4lten i <em>LC_IDENTIFICATION<\/em> s\u00e5 att de pekade p\u00e5 lokaliteten <em>ru_MY<\/em>, men i mitt exempel beh\u00f6vdes inte det, eftersom jag utesl\u00f6t fr\u00e5n att s\u00f6ka lokalarkivet <em>locale-archive<\/em>.<\/p>\n<p><\/p>\n<p>F\u00f6r att <em>localedef<\/em> fungerade med filer i min mapp via variabeln <em>I18NPATH<\/em> kan du l\u00e4gga till en extra katalog f\u00f6r att s\u00f6ka ing\u00e5ngsfiler, och katalogen f\u00f6r att spara bin\u00e4ra filer kan anges som en v\u00e4g med snedstreck:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; I18NPATH=~\/.local\/share\/i18n localedef -i ru_RU -f UTF-8 ~\/.local\/lib\/locale\/ru_MY.UTF-8<\/code><\/pre>\n<p><\/p>\n<p><em>POSIX<\/em> antar att i <em>LANG<\/em> kan skriva absoluta v\u00e4gar till kataloger med lokalfiler som b\u00f6rjar med snedstreck, men <em>glibc<\/em> p\u00e5 <em>Linux<\/em> alla v\u00e4gar anses fr\u00e5n basmappen, som kan \u00f6verskrivas genom variabeln <em>LOCPATH<\/em>. Efter att ha installerat <em>LOCPATH=~\/.local\/lib\/locale\/<\/em> kommer alla filer relaterade till lokalisering att s\u00f6kas endast i min mapp. Arkivet med lokaliteter kommer att ignoreras n\u00e4r den inst\u00e4llda variabeln <em>LOCPATH<\/em> \u00e4r inst\u00e4lld.<\/p>\n<p><\/p>\n<p>H\u00e4r \u00e4r det avg\u00f6rande testet:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=ru_MY.UTF-8 LOCPATH=~\/.local\/lib\/locale\/ sort buhg.txt\nAbakanov Michail;m\u00e5lare\nJolkina Ella;kranoperat\u00f6r\nIvanov Andrej;svetsare\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>Upp med hum\u00f6ret! Vi gjorde det!<\/p>\n<p><\/p>\n<h1 id=\"rabota-nad-oshibkami\">Arbeta med felen<\/h1>\n<p><\/p>\n<p>Jag har redan besvarat fr\u00e5gorna om sortering av str\u00e4ngar som st\u00e4lldes i b\u00f6rjan, men det finns fortfarande n\u00e5gra fr\u00e5gor om fel - synliga och osynliga.<\/p>\n<p><\/p>\n<p>L\u00e5t oss \u00e5terv\u00e4nda till den ursprungliga uppgiften.<\/p>\n<p><\/p>\n<p>Och programmet <em>sort<\/em> och programmet <em>join<\/em> anv\u00e4nder samma str\u00e4ngj\u00e4mf\u00f6relsefunktioner fr\u00e5n <em>glibc<\/em>. Hur kom det sig att <em>join<\/em> gav ett sorteringsfel p\u00e5 str\u00e4ngar sorterade av kommandot <em>sort<\/em> i lokaliteten <em>en_US.UTF-8<\/em>? \u041e\u0442\u0432\u0435\u0442 \u043f\u0440\u043e\u0441\u0442: <em>sort<\/em> j\u00e4mf\u00f6r hela str\u00e4ngen, medan <em>join<\/em> bara j\u00e4mf\u00f6r nyckeln, som som standard \u00e4r b\u00f6rjan av str\u00e4ngen fram till den f\u00f6rsta blankstegssymbolen. I mitt exempel ledde detta till ett felmeddelande eftersom sorteringen av de f\u00f6rsta orden i str\u00e4ngarna inte st\u00e4mde \u00f6verens med sorteringen av hela str\u00e4ngar.<\/p>\n<p><\/p>\n<p>Lokalitet <em>&quot;C&quot;<\/em> garanterar att de sorterade raderna inneh\u00e5ller de inledande delstr\u00e4ngarna fram till det f\u00f6rsta mellanslaget sorterade, men det d\u00f6ljer bara ett fel. Det g\u00e5r att hitta s\u00e5dana data (m\u00e4nniskor med samma efternamn men olika f\u00f6rnamn) som utan felmeddelande skulle ge ett felaktigt resultat vid sammanslagning av filer. Om vi vill att <em>join<\/em> sammansl\u00e5 rader fr\u00e5n filer baserat p\u00e5 namn, s\u00e5 \u00e4r den r\u00e4tta metoden att uttryckligen ange f\u00e4ltseparatorn och sortera efter nyckelf\u00e4ltet, ist\u00e4llet f\u00f6r hela raden. I detta fall kommer sammanslagningen att ske korrekt och det kommer inte att uppst\u00e5 n\u00e5gra fel i n\u00e5gon lokal:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; sort -t ; -k 1 buhg.txt &gt; buhg.srt\n$&gt; sort -t ; -k 1 mail.txt &gt; mail.srt\n$&gt; join -t ; buhg.srt mail.srt &gt; result<\/code><\/pre>\n<p><\/p>\n<p>Ett exempel som har k\u00f6rts framg\u00e5ngsrikt i en kodning <em>CP1251<\/em> har ocks\u00e5 ett annat fel. Faktum \u00e4r att i alla k\u00e4nda distributioner <em>Linux<\/em> finns det ingen kompilerad lokal i paketen <em>ru_RU.CP1251<\/em>. Om den kompilerade lokalen inte hittas, s\u00e5 <em>sort<\/em> anv\u00e4nder den tyst byte-f\u00f6r-byte j\u00e4mf\u00f6relse, vilket vi just observerade.<\/p>\n<p><\/p>\n<p>F\u00f6rresten finns det en annan liten bugg relaterad till avsaknaden av kompilerade lokaler. Kommando <em>LOCPATH=\/tmp locale -a<\/em> visar en lista \u00f6ver alla lokaler i <em>locale-archive<\/em>, men med den inst\u00e4llda variabeln <em>LOCPATH<\/em> \u00e4r dessa lokaler otillg\u00e4ngliga f\u00f6r alla program (inklusive sj\u00e4lva <em>locale<\/em>).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LOCPATH=\/tmp locale -a | grep en_US\nlocale: Kan inte st\u00e4lla in LC_CTYPE till standardlokal: Ingen s\u00e5dan fil eller katalog\nlocale: Kan inte st\u00e4lla in LC_MESSAGES till standardlokal: Ingen s\u00e5dan fil eller katalog\nlocale: Kan inte st\u00e4lla in LC_COLLATE till standardlokal: Ingen s\u00e5dan fil eller katalog\nen_US\nen_US.iso88591\nen_US.iso885915\nen_US.utf8\n\n$&gt; LC_COLLATE=en_US.UTF-8 sort --debug\nsort: anv\u00e4nder 'en_US.UTF-8' sorteringsregler\n\n$&gt; LOCPATH=\/tmp LC_COLLATE=en_US.UTF-8 sort --debug\nsort: anv\u00e4nder enkel byte-j\u00e4mf\u00f6relse<\/code><\/pre>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Slutsats<\/h1>\n<p><\/p>\n<p>Om du \u00e4r en programmerare som \u00e4r van vid att betrakta str\u00e4ngar som en upps\u00e4ttning bytes, s\u00e5 \u00e4r ditt val <em>LC_COLLATE=C<\/em>.<\/p>\n<p><\/p>\n<p>Om du \u00e4r lingvist eller ordboksf\u00f6rfattare, s\u00e5 \u00e4r det b\u00e4st att kompilera din egen lokal.<\/p>\n<p><\/p>\n<p>Om du \u00e4r en vanlig anv\u00e4ndare, s\u00e5 beh\u00f6ver du bara v\u00e4nja dig vid att kommandot <em>ls -a<\/em> returnerar filer som b\u00f6rjar med en punkt, blandat med filer som b\u00f6rjar med en bokstav, och <em>Midnight Commander<\/em>, som anv\u00e4nder sina interna funktioner f\u00f6r att sortera namn, placerar filer som b\u00f6rjar med en punkt i b\u00f6rjan av listan.<\/p>\n<p><\/p>\n<h1 id=\"ssylki\">L\u00e4nkar<\/h1>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\/reports\/tr10\/\">Rapport nr 10 Unicode sorteringsalgoritm <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">Vikt av tecken p\u00e5 unicode.org <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/userguide.icu-project.org\/intro\"><em>ICU<\/em> \u2013 implementation av ett bibliotek f\u00f6r att hantera Unicode fr\u00e5n IBM. <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">Sorteringstest med hj\u00e4lp av <em>ICU<\/em> <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.iso.org\/ittf\/ISO14651_2006_TABLE1_en.txt\">Vikt av tecken i <em>ISO 14651<\/em> <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG20\/docs\/n972-14652ft.pdf\">Beskrivning av filformatet med vikter <em>ISO 14652<\/em> <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=14095\">Diskussion om str\u00e4ngj\u00e4mf\u00f6relse i <em>glibc<\/em><\/a><\/noindex><\/p>\n<p>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/503960\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412\u0441\u0451 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0441 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0430\u0434\u0440\u0435\u0441\u0430\u0445 e-mail \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441 \u0434\u043e\u043b\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0431\u0430\u0437\u044b \u043e\u0442\u0434\u0435\u043b\u0430 \u043a\u0430\u0434\u0440\u043e\u0432. \u041e\u0431\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 \u0431\u044b\u043b\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 \u042e\u043d\u0438\u043a\u043e\u0434 UTF-8 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0441 \u044e\u043d\u0438\u043a\u0441\u043e\u0432\u0441\u043a\u0438\u043c\u0438 \u043a\u043e\u043d\u0446\u0430\u043c\u0438 \u0441\u0442\u0440\u043e\u043a. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 mail.txt \u0418\u0432\u0430\u043d\u043e\u0432 \u0410\u043d\u0434\u0440\u0435\u0439;ia@example.com \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 buhg.txt \u0418\u0432\u0430\u043d\u043e\u0432\u0430 \u0410\u043b\u043b\u0430;\u043c\u0430\u043b\u044f\u0440 \u0401\u043b\u043a\u0438\u043d\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-83055","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412\u0441\u0451 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0441 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0430\u0434\u0440\u0435\u0441\u0430\u0445 e-mail \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a Linux\u2019\u043e\u0432\u0441\u043a\u0438\u0439 sort \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412\u0441\u0451 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0441 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0430\u0434\u0440\u0435\u0441\u0430\u0445 e-mail \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-27T23:42:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-27T23:42:15+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Hur Linux\u2019 sorteringskommando sorterar str\u00e4ngar | ProHoster","description":"Inledning Allt b\u00f6rjade med ett kort skript som skulle sammanfoga information om de anst\u00e4lldas e-postadresser, erh\u00e5llen fr\u00e5n en e-postlista, med.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a Linux\u2019\u043e\u0432\u0441\u043a\u0438\u0439 sort \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 | ProHoster","og:description":"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0412\u0441\u0451 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0441 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0430\u0434\u0440\u0435\u0441\u0430\u0445 e-mail \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441.","og:url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-27T23:42:15+00:00","article:modified_time":"2020-05-27T23:42:15+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"83055","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:26:22","updated":"2022-09-27 19:16:08","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/83055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=83055"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/83055\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=83055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=83055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=83055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}