{"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\/da\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","title":{"rendered":"Hvordan sorterer Linux' sort strenge","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Introduktion<\/h1>\n<p><\/p>\n<p>Det hele begyndte med et kort script, der skulle kombinere oplysninger om adresser <em>e-mail<\/em> fra medarbejdere, indsamlet fra en liste over brugere i nyhedsbrevet, med medarbejdernes stillinger, der blev hentet fra HR-databasen. Begge lister blev eksporteret til tekstfiler i Unicode-kodning <em>UTF-8<\/em> og gemt med Unix-linjeskift.<\/p>\n<p><\/p>\n<p>Indhold. <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>Indhold. <em>buhg.txt<\/em><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ivanova Alla;maler\nElkina Ella;kranf\u00f8rer\nIvanov Andrei;smed\nAbakanov Mikhail;maler<\/code><\/pre>\n<p><\/p>\n<p>For at kombinere blev filerne sorteret med Unix-kommandoen <em>sort<\/em> og givet som input til et Unix-program <em>sammenf\u00f8je<\/em>, som uventet afsluttede med en fejl: <\/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: is not sorted: Ivanov Andrei;smed<\/code><\/pre>\n<p><\/p>\n<p>En visuel gennemgang af sorteringsresultatet viste, at sorteringen generelt var korrekt, men i tilf\u00e6lde af matchende mandlige og kvindelige efternavne kom de kvindelige f\u00f8r de mandlige:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; sort buhg.txt\nAbakanov Mikhail;maler\nElkina Ella;kranf\u00f8rer\nIvanova Alla;maler\nIvanov Andrei;smed<\/code><\/pre>\n<p><\/p>\n<p>Det ser ud som en fejl i Unicode-sorteringen eller som en indikator for feminisme i sorteringsalgoritmen. F\u00f8rstn\u00e6vnte lyder selvf\u00f8lgelig mere sandsynligt.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Lad os udskyde det for nu <em>sammenf\u00f8je<\/em> og fokusere p\u00e5 <em>sort<\/em>. Lad os pr\u00f8ve at l\u00f8se problemet ved hj\u00e6lp af trial and error. F\u00f8rst skifter vi lokaliteten fra <em>en_US<\/em> og f\u00e5 en fungerende kommando. <em>ru_RU<\/em>. For sorteringen ville det have v\u00e6ret tilstr\u00e6kkeligt at indstille milj\u00f8variablen <em>LC_COLLATE<\/em>, men vi vil ikke v\u00e6re sm\u00e5lige:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=ru_RU.UTF-8 sort buhg.txt\nAbakanov Mikhail;maler\nElkina Ella;kranf\u00f8rer\nIvanova Alla;maler\nIvanov Andrei;smed<\/code><\/pre>\n<p><\/p>\n<p>Der \u00e6ndrede sig ikke noget.<\/p>\n<p><\/p>\n<p>Lad os pr\u00f8ve at re-kode filerne til en enbyte-kodning: <\/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>Igen \u00e6ndrede der sig ikke noget.<\/p>\n<p><\/p>\n<p>Der er ikke meget at g\u00f8re, vi m\u00e5 s\u00f8ge l\u00f8sningen p\u00e5 internettet. Der er ikke meget specifikt om russiske efternavne, men der er sp\u00f8rgsm\u00e5l om andre m\u00e6rkelige sorteringer. For eksempel dette problem: <noindex><a rel=\"nofollow\" href=\"https:\/\/serverfault.com\/questions\/95579\/unix-sort-treats-dash-characters-as-invisible\/95593\">Unix sort behandler &#8216;-&#8216; (bindestreg) tegn som usynlige<\/a><\/noindex>. Kort sagt, s\u00e5 sorteres strenge &quot;a-b&quot;, &quot;aa&quot;, &quot;ac&quot; som &quot;aa&quot;, &quot;a-b&quot;, &quot;ac&quot;.<\/p>\n<p><\/p>\n<p>Svaret er overalt standard: brug programmeringslokaliteten <em>&quot;C&quot;<\/em> og du vil v\u00e6re lykkelig. Vi pr\u00f8ver:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=C sort buhg.txt\nElkina Ella;kranf\u00f8rer\nAbakanov Mikhail;maler\nIvanov Andrei;smed\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>Noget har \u00e6ndret sig. Ivanov-familien er nu i den korrekte r\u00e6kkef\u00f8lge, men Elkina er forsvundet et eller andet sted. Lad os vende tilbage til den oprindelige opgave:<\/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 fungerede uden fejl, som internettet lovede. Og det p\u00e5 trods af Jolkin i den f\u00f8rste linje.<\/p>\n<p><\/p>\n<p>Problemet ser ud til at v\u00e6re l\u00f8st, men for en sikkerheds skyld vil vi pr\u00f8ve endnu en russisk kodning \u2014 Windows-versionen. <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>Resultatet af sorteringen vil, underligt nok, v\u00e6re det samme som lokaliteten. <em>&quot;C&quot;<\/em>, og hele eksemplet vil derfor g\u00e5 igennem uden fejl. En eller anden mystik.<\/p>\n<p><\/p>\n<p>Jeg er ikke glad for mystik i programmering, da den normalt skjuler fejl. Jeg m\u00e5 tage sp\u00f8rgsm\u00e5let alvorligt om, hvordan det fungerer <em>sort<\/em> og hvad det p\u00e5virker <em>LC_COLLATE<\/em> .<\/p>\n<p><\/p>\n<p>Til slut vil jeg fors\u00f8ge at svare p\u00e5 sp\u00f8rgsm\u00e5lene:<\/p>\n<p><\/p>\n<ul>\n<li>hvorfor kvindelige efternavne blev sorteret forkert<\/li>\n<li>hvorfor <em>LANG=ru_RU.CP1251<\/em> vist sig at v\u00e6re \u00e6kvivalent med <em>LANG=C<\/em><\/li>\n<li>hvorfor har <em>sort<\/em> og <em>sammenf\u00f8je<\/em> forskellige opfattelser af r\u00e6kkef\u00f8lgen af de sorterede strenge<\/li>\n<li>hvorfor der er fejl i alle mine eksempler<\/li>\n<li>endelig, hvordan man sorterer strenge efter egen smag<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sortirovka-v-yunikode\">Sortering i Unicode<\/h1>\n<p><\/p>\n<p>Den f\u00f8rste stop vil v\u00e6re den tekniske rapport nr. 10 med titlen <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\/reports\/tr10\/\">Unicode collation algorithm<\/a><\/noindex> hjemmeside <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\">unicode.org<\/a><\/noindex>. Rapporten indeholder mange tekniske detaljer, s\u00e5 jeg tillader mig at give et kort resum\u00e9 af hovedideerne.<\/p>\n<p><\/p>\n<p><em>Sammenligning<\/em> \u2014 &quot;komparering&quot; af strenge \u2014 er grundlaget for enhver sorteringsalgoritme. Selve algoritmerne kan variere (&quot;boblesortering&quot;, &quot;samling&quot;, &quot;hurtig&quot;), men de vil alle bruge komparering af par af strenge for at bestemme r\u00e6kkef\u00f8lgen.<\/p>\n<p><\/p>\n<p>Sortering af strenge p\u00e5 naturligt sprog er et ret komplekst problem. Selv i de enkleste en-byte-kodninger vil r\u00e6kkef\u00f8lgen af bogstaverne i alfabetet, som i et eller andet omfang adskiller sig fra det engelske alfabet, ikke l\u00e6ngere stemme overens med r\u00e6kkef\u00f8lgen af de numeriske v\u00e6rdier, som disse bogstaver kodes. S\u00e5 i det tyske alfabet ligger bogstavet <em>\u00d6<\/em> mellem <em>O<\/em> og <em>P<\/em>, og i kodningen <em>CP850<\/em> falder det mellem <em>\u00ff<\/em> og <em>\u00dc<\/em>.<\/p>\n<p><\/p>\n<p>Man kan fors\u00f8ge at abstrahere fra den specifikke kodning og betragte &quot;ideelle&quot; bogstaver, som er placeret i en bestemt r\u00e6kkef\u00f8lge, som det er gjort i Unicode. Kodninger <em>UTF8<\/em>, <em>UTF16<\/em> eller en-byte <em>KOI8-R<\/em> (hvis en begr\u00e6nset delm\u00e6ngde af Unicode er n\u00f8dvendig) vil give forskellige numeriske repr\u00e6sentationer af bogstaverne, men referere til de samme elementer i den grundl\u00e6ggende tabel. <\/p>\n<p><\/p>\n<p>Det viser sig, at selvom vi bygger en tegn tabel fra bunden, kan vi ikke tildele en universel r\u00e6kkef\u00f8lge af tegnene. I forskellige nationale alfabetter, der bruger de samme bogstaver, kan r\u00e6kkef\u00f8lgen af disse bogstaver variere. For eksempel i fransk <em>\u00c6<\/em> vil blive betragtet som en ligatur og sorteres som en streng. <em>AE<\/em>I det norske sprog <em>\u00c6<\/em> vil v\u00e6re et separat bogstav, der kommer efter <em>Z<\/em>. For \u00f8vrigt findes der udover ligaturer af typen <em>\u00c6<\/em> bogstaver, der skrives med flere tegn. S\u00e5 i det tjekkiske alfabet er der et bogstav <em>Ch<\/em>, som st\u00e5r mellem <em>i giver ikke andre deltagere mulighed for at genskabe den private komponent<\/em> og <em>I<\/em>.<\/p>\n<p><\/p>\n<p>Udover forskelle i alfabetterne findes der ogs\u00e5 andre nationale traditioner, der p\u00e5virker sorteringen. S\u00e6rligt opst\u00e5r sp\u00f8rgsm\u00e5let: i hvilken r\u00e6kkef\u00f8lge skal ord best\u00e5ende af store og sm\u00e5 bogstaver f\u00f8lge i ordbogen? Derudover kan brugen af tegns\u00e6tningssymboler p\u00e5virke sorteringen. I spansk s\u00e6ttes der et omvendt sp\u00f8rgsm\u00e5lstegn i begyndelsen af sp\u00f8rgende s\u00e6tninger (<em>\u00bfTe gusta la m\u00fasica?<\/em>). I dette tilf\u00e6lde er det \u00e5benlyst, at sp\u00f8rgende s\u00e6tninger ikke b\u00f8r grupperes i en separat klynge uden for alfabetet, men hvordan sorteres strenge med andre tegns\u00e6tningssymboler?<\/p>\n<p><\/p>\n<p>Jeg vil ikke dv\u00e6le ved sortering af strenge i sprog, der er meget forskellige fra europ\u00e6iske. Jeg bem\u00e6rker, at i sprog med skriftsretning fra h\u00f8jre mod venstre eller oppefra og ned, opbevares tegnene i strenge sandsynligvis i l\u00e6ser\u00e6kkef\u00f8lge, og selv i ikke-alfabetiske skriftformer er der m\u00e5der at ordne strenge p\u00e5 tegn for tegn. For eksempel kan hieroglyffer sorteres efter stregtype (<noindex><a rel=\"nofollow\" href=\"https:\/\/studychinese.ru\/kljuchi\/\">n\u00f8gler til kinesiske hieroglyffer<\/a><\/noindex>) eller efter udtale. Hvordan emojis skal sorteres, ved jeg \u00e6rligt talt ikke, men der kan sikkert findes en l\u00f8sning til dem ogs\u00e5.<\/p>\n<p><\/p>\n<p>Baseret p\u00e5 de ovenfor n\u00e6vnte karakteristika er de grundl\u00e6ggende krav til sammenligning af strenge, der er baseret p\u00e5 Unicode-tabeller, blevet formuleret:<\/p>\n<p><\/p>\n<ul>\n<li>sammenligning af strenge er uafh\u00e6ngig af tegnenes placering i kodetabellen;<\/li>\n<li>sekvenser af tegn, der udg\u00f8r et enkelt tegn, bringes til en kanonisk form (<em>A<\/em> + den \u00f8verste cirkel er det samme som <em>\u00c5<\/em>);<\/li>\n<li>); ved sammenligning af strenge betragtes et tegn i konteksten af strengen og, hvis n\u00f8dvendigt, sammenf\u00f8jes med naboer til en enhed til sammenligning (<em>Ch<\/em> i tjekkisk) eller opdeles i flere (<em>\u00c6<\/em> i fransk);<\/li>\n<li>alle nationale egenskaber (alfabet, versaler \/ minuskler, tegns\u00e6tning, r\u00e6kkef\u00f8lge af skriftsystemer) skal kunne justeres helt ned til manuel tildeling af r\u00e6kkef\u00f8lge (emoji);<\/li>\n<li>sammenligning er vigtig ikke kun for sortering, men ogs\u00e5 p\u00e5 mange andre steder, for eksempel til at angive r\u00e6kkevidder for strenge (substitution {A\u2026 \u044f} i <em>bash<\/em>);<\/li>\n<li>sammenligningen skal udf\u00f8res hurtigt nok.<\/li>\n<\/ul>\n<p><\/p>\n<p>Derudover formulerede rapportforfatterne de egenskaber ved sammenligning, som algoritmeudviklerne ikke b\u00f8r stole p\u00e5:<\/p>\n<p><\/p>\n<ul>\n<li>sammenligningsalgoritmen b\u00f8r ikke kr\u00e6ve et separat tegns\u00e6t for hvert sprog (russisk og ukrainsk bruger f\u00e6lles de fleste kyrilliske tegn);<\/li>\n<li>sammenligningen m\u00e5 ikke bygge p\u00e5 r\u00e6kkef\u00f8lgen af tegn i Unicode-tabeller;<\/li>\n<li>v\u00e6rdien af en streng m\u00e5 ikke v\u00e6re et attribut for strengen, da den samme streng i forskellige kulturelle kontekster kan have forskellige v\u00e6rdier;<\/li>\n<li>strengev\u00e6rdier kan \u00e6ndre sig ved sammenl\u00e6gning eller opdeling (fra <em>x<\/em> &lt; <em>y<\/em> det betyder ikke, at <em>xz<\/em> &lt; <em>yz<\/em>);<\/li>\n<li>forskellige strenge, der har de samme v\u00e6rdier, betragtes som lige i algoritmen for sortering. Introduktion af ekstra r\u00e6kkef\u00f8lge for s\u00e5danne strenge er muligt, men det kan forringe ydeevnen;<\/li>\n<li>ved gentagne sorteringer kan strenge med de samme v\u00e6rdier skifte pladser. Stabilitet er en egenskab ved den specifikke sorteringsalgoritme, ikke en egenskab ved str\u00e6ngesammenligningsalgoritmen (se det forrige punkt);<\/li>\n<li>sorteringsreglerne kan \u00e6ndre sig over tid, efterh\u00e5nden som kulturelle traditioner pr\u00e6ciseres \/ \u00e6ndres.<\/li>\n<\/ul>\n<p><\/p>\n<p>Det er ogs\u00e5 specificeret, at sammenligningsalgoritmen ikke har nogen viden om semantikken for de behandlede strenge. S\u00e5, strenge best\u00e5ende kun af cifre m\u00e5 ikke sammenlignes som tal, og i lister over engelske navne m\u00e5 artiklen ikke fjernes (<em>Beatles, The<\/em>).<\/p>\n<p><\/p>\n<p>For at im\u00f8dekomme alle de angivne krav er der foresl\u00e5et en flerlag (faktisk firelags) tabelsorteringsalgoritme.<\/p>\n<p><\/p>\n<p>Forudg\u00e5ende bliver tegnene i strengen konverteret til kanonisk form og grupperet i sammenligningsenheder. Hver sammenligningsenhed tildeles flere v\u00e6gte, som svarer til flere niveauer af sammenligning. V\u00e6gtene for sammenligningsenhederne er elementer i ordnede m\u00e6ngder (i dette tilf\u00e6lde hele tal), som kan sammenlignes som st\u00f8rre eller mindre. Specialv\u00e6rdien <em>IGNORED<\/em> (0x0) betyder, at den p\u00e5g\u00e6ldende enhed ikke deltager i sammenligningen p\u00e5 det relevante niveau. Sammenligning af strenge kan gentages flere gange ved brug af v\u00e6gte for de relevante niveauer. P\u00e5 hvert af niveauerne sammenlignes v\u00e6gtene for enhederne i de to strenge sekventielt med hinanden.<\/p>\n<p><\/p>\n<p>I forskellige implementeringer af algoritmen kan koefficienterne variere afh\u00e6ngigt af nationale traditioner, men den grundl\u00e6ggende v\u00e6gt-tabel indg\u00e5r i Unicode-standards\u00e6ttet \u2014 <em>&quot;Default Unicode Collation Element Table&quot;<\/em> (<em>DUCET<\/em>). Jeg vil bem\u00e6rke, at indstillingen af variablen <em>LC_COLLATE<\/em> faktisk er en angivelse af valget af v\u00e6gt-tabel i sammenligningsfunktionen.<\/p>\n<p><\/p>\n<p>V\u00e6gtniveauerne <em>DUCET<\/em> er opbygget som f\u00f8lger:<\/p>\n<p><\/p>\n<ul>\n<li>p\u00e5 det f\u00f8rste niveau g\u00f8res alle bogstaver til samme skriftform, diakritiske tegn kasseres, og tegns\u00e6tning (ikke alle) ignoreres;<\/li>\n<li>p\u00e5 det andet niveau tages kun diakritiske tegn i betragtning;<\/li>\n<li>p\u00e5 det tredje niveau tages kun skriftform i betragtning;<\/li>\n<li>p\u00e5 det fjerde niveau tages kun tegns\u00e6tning i betragtning.<\/li>\n<\/ul>\n<p><\/p>\n<p>Sammenligningen foreg\u00e5r i flere gennemgange: f\u00f8rst sammenlignes v\u00e6gtene p\u00e5 f\u00f8rste niveau; hvis v\u00e6gtene stemmer overens, foretages der en ny sammenligning med v\u00e6gtene p\u00e5 andet niveau; derefter eventuelt tredje og fjerde.<\/p>\n<p><\/p>\n<p>Sammenligningen afsluttes, n\u00e5r der findes matchende enheder med forskellige v\u00e6gte i strenge. Strenge med ligelige v\u00e6gte p\u00e5 alle fire niveauer betragtes som identiske.<\/p>\n<p><\/p>\n<p>Denne algoritme (med en masse ekstra tekniske detaljer) gav navn til rapport nr. 10 \u2014 <em>&quot;Unicode Collation Algorithm&quot;<\/em> (<em>UCA<\/em>).<\/p>\n<p><\/p>\n<p>Her bliver sorteringsadf\u00e6rden fra vores eksempel lidt mere forst\u00e5elig. Det ville v\u00e6re godt at sammenligne det med Unicode-standarden.<\/p>\n<p><\/p>\n<p>Til test af implementeringer <em>UCA<\/em> er der en s\u00e6rlig <noindex><a rel=\"nofollow\" href=\"https:\/\/www.unicode.org\/Public\/UCA\/latest\/CollationTest.html\">test<\/a><\/noindex>, der bruger <noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">en v\u00e6gtfil<\/a><\/noindex>, der implementerer <em>DUCET<\/em>. I v\u00e6gtfilen kan man finde forskellige sjove ting. For eksempel findes der r\u00e6kkef\u00f8lgen af mahjong-brikker og europ\u00e6isk dominospil samt r\u00e6kkef\u00f8lgen af farver i et kortspil (symbol <em>1F000<\/em> og videre). Kortfarverne er arrangeret efter bridge-reglerne \u2014 HJDBT, og kortene i hver farve \u2014 i r\u00e6kkef\u00f8lgen 10, 2, 3... K.<\/p>\n<p><\/p>\n<p>Manuel kontrol af korrektheden af sorteringen af strenge i henhold til <em>DUCET<\/em> ville v\u00e6re ret tr\u00e6ttende, men heldigvis for os, findes der en eksemplarisk implementering af et bibliotek til arbejdet med Unicode \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 hjemmesiden til dette bibliotek, udviklet i <em>IBM<\/em>, er der demonstrationssider, herunder <noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">siden for str\u00e6ng sammenligning algoritme<\/a><\/noindex>. Vi indtaster vores teststrenge med standardindstillingerne, og miraklet, vi f\u00e5r den perfekte russiske sortering.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Abakanov Mikhail;maler\nYolkina Ella;kranf\u00f8rer\nIvanov Andrey;vvs'er\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>Forresten, p\u00e5 hjemmesiden <em>ICU<\/em> kan du finde pr\u00e6ciseringen af algoritmens arbejde med hensyn til behandling af tegns\u00e6tning. I eksemplerne <noindex><a rel=\"nofollow\" href=\"http:\/\/userguide.icu-project.org\/collation\/faq\">Collation FAQ<\/a><\/noindex> ignoreres apostrof og bindestreg.<\/p>\n<p><\/p>\n<p>Unicode hjalp os, men vi m\u00e5 lede efter \u00e5rsagerne til den m\u00e6rkelige opf\u00f8rsel <em>sort<\/em> i <em>Linux<\/em> et andet sted.<\/p>\n<p><\/p>\n<h1 id=\"sortirovka-v-glibc\">Sortering i glibc<\/h1>\n<p><\/p>\n<p>En hurtig gennemgang af kildekoden til v\u00e6rkt\u00f8jet <em>sort<\/em> af <em>GNU Core Utils<\/em> viste, at i selve v\u00e6rkt\u00f8jet lokaliseres, n\u00e5r den aktuelle v\u00e6rdi af variablen <em>LC_COLLATE<\/em> startes i fejls\u00f8gningsmodus:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ sort --debug buhg.txt &gt; buhg.srt\nsort: using \u2018en_US.UTF8\u2019 sorting rules<\/code><\/pre>\n<p><\/p>\n<p>Sammenligning af strenge udf\u00f8res af standardfunktionen <em>strcoll<\/em>, og alt det interessante findes i biblioteket <em>glibc<\/em>.<\/p>\n<p><\/p>\n<p>P\u00e5 <em>wiki<\/em> projektet <em>glibc<\/em> er der et afsnit dedikeret til sammenligning af strenge <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/glibc\/wiki\/Locales#LC_COLLATE\">. Fra dette afsnit kan man forst\u00e5, at i<\/a><\/noindex>baserer sorteringen sig p\u00e5 den allerede kendte algoritme <em>glibc<\/em> The Unicode collation algorithm <em>UCA<\/em> (<em>) og\/eller p\u00e5 en n\u00e6rt besl\u00e6gtet standard<\/em>ISO 14651 <em>International string ordering and comparison<\/em> (<em>). Om den sidste standard skal bem\u00e6rkes, at den p\u00e5 hjemmesiden<\/em>standards.iso.org <noindex><a rel=\"nofollow\" href=\"https:\/\/standards.iso.org\/ittf\/PubliclyAvailableStandards\">officielt er erkl\u00e6ret offentligt tilg\u00e6ngelig, men det relevante link f\u00f8rer til en ikke-eksisterende side. Google viser flere sider med links til officielle websteder, der tilbyder at k\u00f8be en elektronisk kopi af standarden for et par hundrede euro, men p\u00e5 den tredje-fjerde side af s\u00f8geresultatet findes der direkte links til<\/a><\/noindex> <em>International string ordering and comparison<\/em> . Alt i alt adskiller standarden sig ikke v\u00e6sentligt fra <em>PDF<\/em>, men det er mere kedeligt at l\u00e6se, da den ikke indeholder markante eksempler p\u00e5 nationale s\u00e6rtr\u00e6k i str\u00e6ns sortering. <em>UCA<\/em>Den mest interessante information p\u00e5 <\/p>\n<p><\/p>\n<p>var linket til <em>wiki<\/em> bugtracker <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=14095\">med diskussionen om implementeringen af str\u00e6ng sammenligning i<\/a><\/noindex> . Fra diskussionen kan man l\u00e6re, at i <em>glibc<\/em>bruges <em>glibc<\/em> den f\u00e6lles tabel <em>ISO<\/em>The Common Template Table <noindex><a rel=\"nofollow\" href=\"http:\/\/www.iso.org\/ittf\/ISO14651_2006_TABLE1_en.txt\">CTT<\/a><\/noindex> (<em>), hvis adresse kan findes i bilaget<\/em>til standarden <em>A<\/em> . Mellem 2000 og 2015 var denne tabel i <em>International string ordering and comparison<\/em>. Mellem 2000 og 2015 var denne tabel i <em>glibc<\/em> var ikke en maintainer og adskilte sig meget (i det mindste visuelt) fra den nuv\u00e6rende standardversion. Fra 2015 til 2018 blev der arbejdet p\u00e5 tilpasning til den nye version af tabellen, og i \u00f8jeblikket har du mulighed for at m\u00f8de b\u00e5de den nye version af tabellen (<em>CentOS 8<\/em>), s\u00e5vel som den gamle (<em>CentOS 7<\/em>). <\/p>\n<p><\/p>\n<p>Nu hvor vi har al information om algoritmen og hj\u00e6lpe-tabellerne, kan vi vende tilbage til det oprindelige problem og forst\u00e5, hvordan man korrekt sorterer strenge i den russiske lokalitet.<\/p>\n<p><\/p>\n<h1 id=\"iso-1465114652\">ISO 14651\/14652<\/h1>\n<p><\/p>\n<p>Kilden til den tabel, vi er interesseret i <em>), hvis adresse kan findes i bilaget<\/em> findes i de fleste distributioner <em>Linux<\/em> i mappen <em>\/usr\/share\/i18n\/locales\/<\/em>. Selve tabellen findes i filen <em>iso14651_t1_common<\/em>. Derefter inkluderes denne fil med direktivet <em>copy iso14651_t1_common<\/em> i filen <em>iso14651_t1<\/em>, som i sin tur inkluderes i de nationale filer, herunder i <em>en_US<\/em> og <em>ru_RU<\/em>. I de fleste distributioner <em>Linux<\/em> alle kildefiler er inkluderet i den grundl\u00e6ggende installation, men hvis de ikke er der, skal du installere en ekstra pakke fra distributionen.<\/p>\n<p><\/p>\n<p>Strukturen af filen <em>iso14651_t1<\/em> kan virke frygteligt ordret, med uklare regler for navneopbygning, men hvis du f\u00f8rst forst\u00e5r det, s\u00e5 er alt ret simpelt. Strukturen er beskrevet i standarden <em>ISO 14652<\/em>, en kopi af hvilken kan downloades fra webstedet <noindex><a rel=\"nofollow\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG20\/docs\/n972-14652ft.pdf\">open-std.org<\/a><\/noindex>. Yderligere en beskrivelse af filformatet kan l\u00e6ses i <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/basedefs\/V1_chap07.html\">specifikationer<\/a><\/noindex> <em>POSIX<\/em> fra <em>OpenGroup<\/em>. Som et alternativ til at l\u00e6se standarden kan du studere kildekoden til funktionen <em>collate_read<\/em> i <em>glibc\/locale\/programs\/ld-collate.c<\/em>.<\/p>\n<p><\/p>\n<p>Filstrukturen ser s\u00e5ledes ud:<\/p>\n<p><\/p>\n<p>Som standard anvendes symbolet som escape-tegn, og slutningen af linjen efter symbolet # er en kommentar. Begge symboler kan overskrives, hvilket ogs\u00e5 er gjort i den nye version af tabellen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">escape_char \/\ncomment_char %<\/code><\/pre>\n<p><\/p>\n<p>I filen vil der v\u00e6re tokens i formatet <em>&lt;Uxxxx&gt;<\/em> eller <em>&lt;Uxxxxxxxx&gt;<\/em> (hvor <em>x<\/em> \u2014 hexadecimale cifre). Dette er den hexadecimale repr\u00e6sentation af Unicode-kodepunkter i kodningen <em>UCS-4<\/em> (<em>UTF-32<\/em>). Alle andre elementer i vinkelparenteser (herunder <em>&lt;Uxxxx_xxxx&gt;<\/em>, <em>&lt;2&gt;<\/em> og lignende), betragtes som simple strengekonstanter, der ikke har nogen s\u00e6rlig betydning uden for konteksten.<\/p>\n<p><\/p>\n<p>Streng <em>LC_COLLATE<\/em> fort\u00e6ller os, at dataene, der beskriver sammenligning af strenge, begynder her.<\/p>\n<p><\/p>\n<p>F\u00f8rst angives navne til v\u00e6gtene i sammenligningstabellen og navne til kombinationer af tegn. Generelt tilh\u00f8rer de to typer navne to forskellige enheder, men i den faktiske fil er de blandet sammen. Navne til v\u00e6gte angives med n\u00f8gleordet <em>collating-symbol<\/em> (sammenligningssymbol), da tegn i Unicode, der har samme v\u00e6gt, betragtes som \u00e6kvivalente tegn ved sammenligning.<\/p>\n<p><\/p>\n<p>Den samlede l\u00e6ngde af sektionen i den nuv\u00e6rende filrevision er omkring 900 linjer. Jeg har taget eksempler fra flere steder for at vise tilf\u00e6ldigheden af navne og forskellige typer syntaks.<\/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; % Garanteret st\u00f8rste symbolv\u00e6rdi. Holdes i slutningen af denne liste\n...\ncollating-element &lt;U0413_0301&gt; fra &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;\ncollating-element &lt;U0413_0341&gt; fra &quot;&lt;U0413&gt;&lt;U0341&gt;&quot;<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><em>collating-symbol<\/em> registrerer strengen <em>OSMANYA<\/em> i v\u00e6gt tabel <\/li>\n<li><em>collating-symbol ..<\/em> registrerer en sekvens af navne best\u00e5ende af et pr\u00e6fiks <em>Angreb op til 1,2<\/em> og et hexadecimalt nummer suffiks fra <em>1D000<\/em> op til <em>1D35F<\/em>.<\/li>\n<li><em>FFFF<\/em> i <em>collating-symbol<\/em> ser ud som et stort usigneret heltal i hexadecimalt system, men <em>&lt;SFFFF&gt;<\/em> det er blot et navn, som kunne se s\u00e5dan ud som <em>&lt;VERYBIGVAL&gt;<\/em> <\/li>\n<li>navn <em>&lt;U0413&gt;<\/em> betyder en kodepunkt i kodningen <em>UCS-4<\/em><\/li>\n<li><em>collating-element &lt;U0413_0301&gt; fra &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;<\/em> registrerer et nyt navn for et par Unicode punkter. <\/li>\n<\/ul>\n<p><\/p>\n<p>N\u00e5r v\u00e6gtnavne er defineret, angives de faktiske v\u00e6gte. Da det kun er forholdet st\u00f8rre-mindre, der er vigtigt i kompareringen, bestemmes v\u00e6gtene af en simpel sekvens af opregning af navne. F\u00f8rst listes de &quot;lettere&quot; v\u00e6gte, og derefter de &quot;tyngre&quot;. Jeg minder om, at hver Unicode-tegn tildeles fire forskellige v\u00e6gte. Her er de samlet i en enkelt ordnet sekvens. Teoretisk kan ethvert symbolsk navn bruges p\u00e5 et af de fire niveauer, men kommentarer angiver, at udviklerne mentalt opdeler navnene efter niveauer.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">% Symbolske v\u00e6gt tildelinger\n\n% Tredje-niveau v\u00e6gt tildelinger\n\n\n\n\n...\n% Andet-niveau v\u00e6gt tildelinger\n\n % KOMBINERENDE LAV LINIE\n % KOMBINERENDE KOMMA OVENFOR\n % KOMBINERENDE OMVENDT KOMMA OVENFOR\n...\n% F\u00f8rste-niveau v\u00e6gt tildelinger\n % HORISONTAL TABULERING\n % LINJE SKIFT\n % VERTIKAL TABULERING\n...\n % CYRILSK LILLE BOGSTAV DE\n % CYRILSK LILLE BOGSTAV KOMI DE\n % CYRILSK LILLE BOGSTAV DJE\n % CYRILSK LILLE BOGSTAV KOMI DJE\n % CYRILSK LILLE BOGSTAV GJE\n % CYRILSK LILLE BOGSTAV ZE MED DESCENDER\n % CYRILSK LILLE BOGSTAV IE\n % CYRILSK LILLE BOGSTAV IE MED BREVE\n % CYRILSK LILLE BOGSTAV UKRAINISK IE\n % CYRILSK LILLE BOGSTAV ZHE<\/code><\/pre>\n<p><\/p>\n<p>Endelig selve v\u00e6gt-tabellen.<\/p>\n<p><\/p>\n<p>V\u00e6gtsektionen er indkapslet i r\u00e6kker med n\u00f8gleord <em>order_start<\/em> og <em>order_end<\/em>. Yderligere parametre <em>order_start<\/em> bestemmer, i hvilken retning r\u00e6kkerne vises p\u00e5 hvert sammenligningsniveau. Som standard bruges parameteren <em>forward<\/em>. Sektionens krop best\u00e5r af r\u00e6kker, der indeholder tegnkode og fire v\u00e6gte. Tegnkoden kan pr\u00e6senteres som selve tegnet, som kodepunktet eller som et symbolsk navn, der er defineret tidligere. V\u00e6gte kan ogs\u00e5 angives ved symbolske navne, kodepunkter eller selve tegnene. Hvis kodepunkter eller tegn bruges, svarer deres v\u00e6gt til det numeriske v\u00e6rdien af kodepunktet (positionen i Unicode-tabellen). Tegn, der ikke er specificeret eksplicit (som jeg forst\u00e5r), betragtes som tilknyttede i tabellen med en prim\u00e6r v\u00e6gt svarende til positionen i Unicode-tabellen. Den specielle v\u00e6gtv\u00e6rdi <em>IGNORE<\/em> betyder, at det p\u00e5g\u00e6ldende tegn ignoreres p\u00e5 det relevante sammenligningsniveau.<\/p>\n<p><\/p>\n<p>For at demonstrere v\u00e6gtstrukturen har jeg valgt tre ret indlysende fragmenter:<\/p>\n<p><\/p>\n<ul>\n<li>tegn, der ignoreres helt<\/li>\n<li>tegn svarende til tallet tre p\u00e5 de f\u00f8rste to niveauer<\/li>\n<li>begyndelsen af det kyrilliske alfabet, som ikke indeholder diakritiske tegn, og derfor sorteres hovedsageligt efter det f\u00f8rste og tredje niveau.<\/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 vende tilbage til sorteringen af eksemplerne fra begyndelsen af artiklen. Problemet ligger i denne del af v\u00e6gt-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 er tydeligt, at denne tabel indeholder tegns\u00e6tning fra tabellen <em>ASCII<\/em> (inklusive mellemrum) ved sammenligning af strenge ignoreres stort set altid. Undtagelsen er kun strenge, der er identiske i alt andet end tegns\u00e6tning, der optr\u00e6der i samme positioner. Strenge fra mit eksempel (efter sortering) vises s\u00e5ledes til sammenligningsalgoritmen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">AbakanovMikhailMalear\nJolkinaEllakranovschitsa\nIvanovaAllamalear\nIvanovAndreiSmed<\/code><\/pre>\n<p><\/p>\n<p>Da store bogstaver i det russiske sprog kommer efter sm\u00e5 bogstaver i v\u00e6gtabellen (p\u00e5 tredje niveau <em>&lt;CAP&gt;<\/em> tungere end <em>&lt;MIN&gt;<\/em>), ser sorteringen helt korrekt ud.<\/p>\n<p><\/p>\n<p>Ved at indstille variablen <em>LC_COLLATE=C<\/em> indl\u00e6ses en s\u00e6rlig tabel, som angiver byte-for-byte sammenligning<\/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>Da Unicode-kodepunktet for \u0401 ligger f\u00f8r \u0410, sorteres strenge i overensstemmelse hermed.<\/p>\n<p><\/p>\n<h1 id=\"tekstovye-i-dvoichnye-tablicy\">Tekst- og bin\u00e6rtabeller<\/h1>\n<p><\/p>\n<p>Det er indlysende, at sammenligning af strenge er en ekstremt hyppig operation, mens analysen af tabellen <em>), hvis adresse kan findes i bilaget<\/em> er en ret kostbar procedure. For at optimere adgangen til tabellen kompilere den i bin\u00e6r form ved hj\u00e6lp af kommandoen <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Kommandoen <em>localedef<\/em> modtager som parametre en fil med tabellen for nationale kendetegn (option <em>-i<\/em>), hvor alle tegn er repr\u00e6senteret af Unicode punkter, og en fil med overensstemmelse mellem Unicode punkter og tegn fra en bestemt kodning (option <em>-f<\/em>). Som resultat af arbejdet skabes der bin\u00e6re filer til lokaliteten med det navn, der er angivet i den sidste parameter.<\/p>\n<p><\/p>\n<p><em>Glibc<\/em> underst\u00f8tter to formater for bin\u00e6re filer: &quot;traditionelt&quot; og &quot;moderne&quot;.<\/p>\n<p><\/p>\n<p>Det traditionelle format indeb\u00e6rer, at navnet p\u00e5 lokaliteten er navnet p\u00e5 en undermappe i <em>\/usr\/lib\/locale\/<\/em>. I denne undermappe opbevares bin\u00e6re filer <em>LC_COLLATE<\/em>, <em>LC_CTYPE<\/em>, <em>LC_TIME<\/em> og s\u00e5 videre. Filen <em>LC_IDENTIFICATION<\/em> indeholder det formelle navn p\u00e5 lokaliteten (som muligvis adskiller sig fra mappenavnet) og kommentarer.<\/p>\n<p><\/p>\n<p>Det moderne format foruds\u00e6tter opbevaring af alle lokaliteter i et enkelt arkiv <em>\/usr\/lib\/locale\/locale-archive<\/em>, som kortl\u00e6gges til den virtuelle hukommelse i alle processer, der bruger <em>glibc<\/em>Navnet p\u00e5 lokaliteten i det moderne format uds\u00e6ttes for en vis kanonisering - i navnene p\u00e5 kodninger bevares kun tal og bogstaver, der er omdannet til sm\u00e5 bogstaver. S\u00e5 <em>ru_RU.KOI8-R<\/em>, vil blive gemt som <em>ru_RU.koi8r<\/em>.<\/p>\n<p><\/p>\n<p>Indgangsfiler findes i den aktuelle katalog samt i katalogerne <em>\/usr\/share\/i18n\/locales\/<\/em> og <em>\/usr\/share\/i18n\/charmaps\/<\/em> for filer <em>), hvis adresse kan findes i bilaget<\/em> og filer med kodninger henholdsvis.<\/p>\n<p><\/p>\n<p>For eksempel vil kommandoen<\/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>kompilere filen <em>\/usr\/share\/i18n\/locales\/ru_RU<\/em> ved brug af kodningsfilen <em>\/usr\/share\/i18n\/charmaps\/MAC-CYRILLIC.gz<\/em> og gemme resultatet i <em>\/usr\/lib\/locale\/locale-archive<\/em> med navnet <em>ru_RU.maccyrillic<\/em><\/p>\n<p><\/p>\n<p>Hvis variablen <em>LANG=en_US.UTF-8<\/em> s\u00e5 <em>glibc<\/em> vil kigge efter bin\u00e6re filer til lokaliteten i f\u00f8lgende sekvens af filer og 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>Hvis lokaliteten findes b\u00e5de i traditionelle og moderne formater, gives der prioritet til den moderne.<\/p>\n<p><\/p>\n<p>For at se listen over kompileringer af lokaliteter kan kommandoen <em>locale -a<\/em>.<\/p>\n<p><\/p>\n<h1 id=\"podgotovka-svoey-tablicy-sravneniya\">Forberedelse af din egen sammenligningstabel<\/h1>\n<p><\/p>\n<p>Nu, bev\u00e6bnet med viden, kan du oprette din egen ideelle sammenligningstabel. Denne tabel skal korrekt sammenligne russiske bogstaver, inklusive bogstavet \u0401, og tage h\u00f8jde for tegns\u00e6tningsm\u00e6rker i overensstemmelse med tabellen <em>ASCII<\/em>.<\/p>\n<p><\/p>\n<p>Processen med at forberede sin egen sorteringstabel best\u00e5r af to trin: redigering af v\u00e6gt tabellen og kompilering af den til bin\u00e6r form via kommandoen <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>For at sorteringstabellen kan tilpasses med minimale redigeringsomkostninger, er der sektioner til justering af v\u00e6gtene i den eksisterende tabel i formatet <em>ISO 14652<\/em> som giver mulighed for at angive en sektion. <em>Sektionen starter med n\u00f8gleordet<\/em> reorder-after <em>og angivelsen af positionen, efter hvilken udskiftningen udf\u00f8res. Sektionen afsluttes med linjen<\/em>reorder-end<\/p>\n<p><\/p>\n<p>. Hvis det er n\u00f8dvendigt at rette flere dele af tabellen, oprettes en sektion for hver del. <em>iso14651_t1_common<\/em> og <em>ru_RU<\/em> fra repository <em>glibc<\/em> Jeg har kopieret de nye versioner af filerne <em>LC_COLLATE<\/em> i <em>ru_RU<\/em>til min hjemmebibliotek ~\/.local\/share\/i18n\/locales\/ og redigeret sektionen lidt. <em>glibc<\/em>De nye versioner af filerne er fuldt kompatible med min version.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">LC_COLLATE\n% Kopier skabelonen fra 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; % MIDDLE\n&lt;U0021&gt; &lt;S0021&gt;;&lt;BASE&gt;&lt;MIN&gt;&lt;U0021&gt; % UDRIDENDE TEGN\n&lt;U0022&gt; &lt;S0022&gt;;&lt;BASE&gt;&lt;MIN&gt;&lt;U0022&gt; % CITATTEGN\n...\n&lt;U007D&gt; &lt;S007D&gt;;&lt;BASE&gt;&lt;MIN&gt;&lt;U007D&gt; % H\u00d8JRE KURVET FIGUR\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>I virkeligheden skulle felterne \u00e6ndres i <em>LC_IDENTIFICATION<\/em> s\u00e5 de peger p\u00e5 lokaliteten <em>da_MY<\/em>, men i mit eksempel var det ikke n\u00f8dvendigt, da jeg udelukkede lokalarkivet fra s\u00f8gningen <em>locale-archive<\/em>.<\/p>\n<p><\/p>\n<p>For at <em>localedef<\/em> arbejdede med filer i min mappe gennem variablen <em>I18NPATH<\/em> man kan tilf\u00f8je en ekstra katalog til at s\u00f8ge i de indg\u00e5ende filer, og kataloget til opbevaring af bin\u00e6re filer kan angives som en sti med skr\u00e5streger:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; I18NPATH=~\/.local\/share\/i18n localedef -i da_DK -f UTF-8 ~\/.local\/lib\/locale\/da_MY.UTF-8<\/code><\/pre>\n<p><\/p>\n<p><em>POSIX<\/em> betyder, at i <em>LANG<\/em> man kan skrive absolutte stier til kataloger med lokalefiler, der begynder med en direkte skr\u00e5streg, men <em>glibc<\/em> i <em>Linux<\/em> alle stier bliver betragtet fra basis-kataloget, som kan overskrives gennem variablen <em>LOCPATH<\/em>. Efter indstillingen <em>LOCPATH=~\/.local\/lib\/locale\/<\/em> vil alle filer relateret til lokalisering kun blive s\u00f8gt i min mappe. Arkivet af lokaliteter med den indstillede variabel <em>LOCPATH<\/em> ignoreres.<\/p>\n<p><\/p>\n<p>Her er den afg\u00f8rende test:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=da_MY.UTF-8 LOCPATH=~\/.local\/lib\/locale\/ sort buhg.txt\nAbakanov Mikhail;maler\nYolkinna Ella;kranoperat\u00f8r\nIvanov Andrey;smed\nIvanova Alla;advokat<\/code><\/pre>\n<p><\/p>\n<p>Hurra! Vi gjorde det!<\/p>\n<p><\/p>\n<h1 id=\"rabota-nad-oshibkami\">Fejlretning<\/h1>\n<p><\/p>\n<p>Jeg har allerede besvaret sp\u00f8rgsm\u00e5lene om sortering af strenge, der blev stillet i starten, men der er stadig et par sp\u00f8rgsm\u00e5l om fejl - b\u00e5de synlige og usynlige.<\/p>\n<p><\/p>\n<p>Lad os vende tilbage til den oprindelige opgave.<\/p>\n<p><\/p>\n<p>Og programmet <em>sort<\/em> og programmet <em>sammenf\u00f8je<\/em> bruger de samme funktionsmetoder til sammenligning af strenge fra <em>glibc<\/em>. Hvordan kunne det v\u00e6re, at <em>sammenf\u00f8je<\/em> gav en sorteringsfejl p\u00e5 strenge, der var sorteret med kommandoen <em>sort<\/em> i lokaliteten <em>en_US.UTF-8<\/em>? \u041e\u0442\u0432\u0435\u0442 \u043f\u0440\u043e\u0441\u0442: <em>sort<\/em> sammenligner hele strengen, mens <em>sammenf\u00f8je<\/em> kun sammenligner n\u00f8glen, som som standard er begyndelsen af strengen op til det f\u00f8rste mellemrum. I mit eksempel f\u00f8rte det til en fejlmeddelelse, da sorteringen af de f\u00f8rste ord i strengene ikke stemte overens med sorteringen af de fulde strenge.<\/p>\n<p><\/p>\n<p>Lokaliteten <em>&quot;C&quot;<\/em> garanterer, at de sorterede strenge ogs\u00e5 har deres startunderskaber op til det f\u00f8rste mellemrum sorteret, men det maskerer kun fejlen. Man kan finde data (folk med ens efternavne, men forskellige fornavne), der uden fejlmeddelelse ville give forkerte resultater ved sammensmeltning af filer. Hvis vi \u00f8nsker, at <em>sammenf\u00f8je<\/em> sammensmelte strenge fra filer efter fulde navne, vil den rette m\u00e5de v\u00e6re at angive feltseparatoren eksplicit og sortere efter n\u00f8glefeltet, ikke efter hele strengen. I dette tilf\u00e6lde vil sammensmeltningen ogs\u00e5 ske korrekt, og der vil ikke v\u00e6re fejl i nogen lokalitet:<\/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>Et vellykket eksempel i kodningen <em>CP1251<\/em> indeholder endnu en fejl. Det er s\u00e5dan, at i alle de distributioner, jeg kender til, <em>Linux<\/em> mangler de kompilerede lokaler i pakkerne <em>ru_RU.CP1251<\/em>. Hvis den kompilerede lokal ikke findes, s\u00e5 <em>sort<\/em> bruger den stille og roligt byte-for-byte sammenligning, hvilket vi observerede.<\/p>\n<p><\/p>\n<p>Forresten, der er en lille bug relateret til den utilg\u00e6ngelige kompilerede lokal. Kommandoen <em>LOCPATH=\/tmp locale -a<\/em> giver en liste over alle lokaler i <em>locale-archive<\/em>, men med den indstillede variabel <em>LOCPATH<\/em> for alle programmer (inklusive selve <em>locale<\/em>) vil disse lokaler v\u00e6re utilg\u00e6ngelige.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LOCPATH=\/tmp locale -a | grep en_US\nlocale: Kan ikke indstille LC_CTYPE til standard lokal: Ingen s\u00e5dan fil eller mappe\nlocale: Kan ikke indstille LC_MESSAGES til standard lokal: Ingen s\u00e5dan fil eller mappe\nlocale: Kan ikke indstille LC_COLLATE til standard lokal: Ingen s\u00e5dan fil eller mappe\nen_US\nen_US.iso88591\nen_US.iso885915\nen_US.utf8\n\n$&gt; LC_COLLATE=en_US.UTF-8 sort --debug\nsort: bruger \u2018en_US.UTF-8\u2019 sorteringsregler\n\n$&gt; LOCPATH=\/tmp LC_COLLATE=en_US.UTF-8 sort --debug\nsort: bruger simpel byte sammenligning<\/code><\/pre>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Konklusion<\/h1>\n<p><\/p>\n<p>Hvis du er en programm\u00f8r, der er vant til at t\u00e6nke p\u00e5 strenge som et s\u00e6t bytes, s\u00e5 er dit valg <em>LC_COLLATE=C<\/em>.<\/p>\n<p><\/p>\n<p>Hvis du er lingvist eller ordbogsforfatter, s\u00e5 er det bedst for dig at kompilere din egen lokal.<\/p>\n<p><\/p>\n<p>Hvis du er en almindelig bruger, s\u00e5 er det nok for dig at v\u00e6nne dig til, at kommandoen <em>ls -a<\/em> viser filer, der begynder med punktum, blandet med filer, der begynder med bogstavet, og <em>Midnight Commander<\/em>, som bruger sine interne funktioner til at sortere navne, placerer filer, der begynder med punktum, i starten af listen.<\/p>\n<p><\/p>\n<h1 id=\"ssylki\">Links<\/h1>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\/reports\/tr10\/\">Rapport nr. 10 Unicode sammenligningsalgoritme <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">Symbolv\u00e6gte 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> \u2014 implementering af en biblioteksfunktion til arbejde med Unicode fra IBM. <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">Test af sortering ved hj\u00e6lp af <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\">Symbolv\u00e6gte i <em>International string ordering and comparison<\/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\">Beskrivelse af filformatet med v\u00e6gte <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 af strengsammenligning i <em>glibc<\/em><\/a><\/noindex><\/p>\n<p>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47S\u00e5dan sorterer Linux'ens sort strenge | ProHoster","description":"Introduktion Alt begyndte med et kort script, som skulle samle information om medarbejderes e-mail adresser, indsamlet fra en liste over mailinglistebrugere, med.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/83055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=83055"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/83055\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=83055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=83055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=83055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}