{"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\/de\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","title":{"rendered":"Wie der Linux-Sort-Befehl Zeichenfolgen sortiert.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Einf\u00fchrung<\/h1>\n<p><\/p>\n<p>Alles begann mit einem kurzen Skript, das Informationen \u00fcber Adressen <em>E-Mail<\/em> von Mitarbeitern, die aus einer Liste von Newsletter-Abonnenten stammen, mit den Positionen der Mitarbeiter, die aus der Personalabteilung abgeleitet wurden, zu verbinden. Beide Listen wurden in Textdateien im Unicode-Format exportiert <em>UTF-8<\/em> und mit UNIX-Zeilenenden gespeichert.<\/p>\n<p><\/p>\n<p>Inhalt <em>mail.txt<\/em><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ivanov Andrej;ia@example.com<\/code><\/pre>\n<p><\/p>\n<p>Inhalt <em>buhg.txt<\/em><\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ivanova Alla;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanov Andrej;Installateur\nAbakanov Michail;Maler<\/code><\/pre>\n<p><\/p>\n<p>Um die Dateien zu kombinieren, wurden sie mit dem UNIX-Befehl sortiert <em>sortieren<\/em> und an das UNIX-Programm \u00fcbergeben <em>join<\/em>, das unerwartet mit einem Fehler endete: <\/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: ist nicht sortiert: Ivanov Andrej;Installateur<\/code><\/pre>\n<p><\/p>\n<p>Ein Blick auf das Sortierungsergebnis zeigte, dass die Sortierung im Gro\u00dfen und Ganzen korrekt ist, aber im Falle von \u00fcbereinstimmenden m\u00e4nnlichen und weiblichen Nachnamen, die weiblichen vor den m\u00e4nnlichen stehen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; sort buhg.txt\nAbakanov Michail;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanova Alla;Maler\nIvanov Andrej;Installateur<\/code><\/pre>\n<p><\/p>\n<p>Es sieht nach einem Sortierfehler in Unicode oder nach einer Auspr\u00e4gung des Feminismus im Sortieralgorithmus aus. Letzteres ist nat\u00fcrlich glaubw\u00fcrdiger.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Lassen wir das vorerst <em>join<\/em> und konzentrieren wir uns auf <em>sortieren<\/em>. Lassen Sie uns versuchen, das Problem mit wissenschaftlichem Versuch und Irrtum zu l\u00f6sen. Zun\u00e4chst \u00e4ndern wir die Locale von <em>en_US<\/em> auf <em>ru_RU<\/em>. F\u00fcr die Sortierung w\u00e4re es ausreichend gewesen, die Umgebungsvariable <em>LC_COLLATE<\/em>, aber wir wollen uns nicht kleinlich zeigen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=ru_RU.UTF-8 sort buhg.txt\nAbakanov Michail;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanova Alla;Maler\nIvanov Andrej;Installateur<\/code><\/pre>\n<p><\/p>\n<p>Es hat sich nichts ge\u00e4ndert.<\/p>\n<p><\/p>\n<p>Lassen Sie uns versuchen, die Dateien in ein einbyte-Format zu kodieren: <\/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>Wieder hat sich nichts ge\u00e4ndert.<\/p>\n<p><\/p>\n<p>Was soll's, wir m\u00fcssen eine L\u00f6sung im Internet suchen. Kurz \u00fcber russische Nachnamen ist nichts vorhanden, aber es gibt Fragen \u00fcber andere Sortieranomalien. Zum Beispiel gibt es folgendes Problem: <noindex><a rel=\"nofollow\" href=\"https:\/\/serverfault.com\/questions\/95579\/unix-sort-treats-dash-characters-as-invisible\/95593\">Unix sort behandelt &#8216;-&#8216; (Bindestrich) Zeichen als unsichtbar<\/a><\/noindex>. Kurz gesagt, die Strings &quot;a-b&quot;, &quot;aa&quot;, &quot;ac&quot; werden als &quot;aa&quot;, &quot;a-b&quot;, &quot;ac&quot; sortiert.<\/p>\n<p><\/p>\n<p>Die Antwort ist \u00fcberall dieselbe: Nutzen Sie die Programmierlokalit\u00e4t <em>&quot;C&quot;<\/em> und Sie werden gl\u00fccklich sein. Probieren wir es aus:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=C sort buhg.txt\nJolkina Ella;Kranf\u00fchrerin\nAbakanov Michail;Maler\nIvanov Andrej;Installateur\nIvanova Alla;Rechtsanw\u00e4ltin<\/code><\/pre>\n<p><\/p>\n<p>Etwas hat sich ge\u00e4ndert. Die Ivanovs sind in der richtigen Reihenfolge angeordnet, aber Jolkina ist irgendwo hin verschwunden. Kehren wir zur urspr\u00fcnglichen Aufgabe zur\u00fcck:<\/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>Es hat ohne Fehler funktioniert, wie das Internet versprochen hat. Und das trotz Jolkino in der ersten Zeile.<\/p>\n<p><\/p>\n<p>Das Problem scheint gel\u00f6st zu sein, aber zur Sicherheit probieren wir noch eine russische Kodierung \u2014 die Windows-Kodierung. <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>Das Sortierungsergebnis wird merkw\u00fcrdigerweise mit der Locale \u00fcbereinstimmen. <em>&quot;C&quot;<\/em>, und das gesamte Beispiel wird entsprechend ohne Fehler durchlaufen. Irgendeine Mystik.<\/p>\n<p><\/p>\n<p>Ich mag keine Mystik in der Programmierung, da sie in der Regel Fehler maskiert. Ich werde mich ernsthaft mit der Frage besch\u00e4ftigen, wie es funktioniert. <em>sortieren<\/em> und auf was es Einfluss hat. <em>LC_COLLATE<\/em> .<\/p>\n<p><\/p>\n<p>Am Ende werde ich versuchen, die Fragen zu beantworten:<\/p>\n<p><\/p>\n<ul>\n<li>warum die weiblichen Nachnamen falsch sortiert wurden.<\/li>\n<li>warum <em>LANG=ru_RU.CP1251<\/em> war ein \u00c4quivalent. <em>LANG=C<\/em><\/li>\n<li>warum <em>sortieren<\/em> und <em>join<\/em> verschiedene Darstellungen der Reihenfolge der sortierten Zeilen existieren.<\/li>\n<li>warum in all meinen Beispielen Fehler vorhanden sind.<\/li>\n<li>schlie\u00dflich, wie man die Zeilen nach eigenem Geschmack sortiert.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sortirovka-v-yunikode\">Sortierung in Unicode.<\/h1>\n<p><\/p>\n<p>Der erste Halt wird der technische Bericht Nr. 10 mit dem Titel <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\/reports\/tr10\/\">Unicode-Kollationsalgorithmus<\/a><\/noindex> auf der Website <noindex><a rel=\"nofollow\" href=\"https:\/\/unicode.org\">unicode.org<\/a><\/noindex>. Der Bericht enth\u00e4lt viele technische Details, daher erlaube ich mir, eine Zusammenfassung der Hauptideen zu geben.<\/p>\n<p><\/p>\n<p><em>Kollation<\/em> \u2014 &quot;Vergleich&quot; von Strings ist die Grundlage jedes Sortieralgorithmus. Die Algorithmen k\u00f6nnen unterschiedlich sein (&quot;Bubble-Sort&quot;, &quot;Merge-Sort&quot;, &quot;Quick-Sort&quot;), aber sie alle verwenden den Vergleich von Paaren von Strings, um die Reihenfolge zu bestimmen.<\/p>\n<p><\/p>\n<p>Die Sortierung von Zeichenfolgen in nat\u00fcrlicher Sprache ist ein recht komplexes Problem. Selbst in den einfachsten Ein-Byte-Kodierungen stimmt die Reihenfolge der Buchstaben im Alphabet, sofern sie sich von der englischen lateinischen Schrift unterscheidet, bereits nicht mehr mit der Reihenfolge der numerischen Werte \u00fcberein, die diese Buchstaben kodieren. So steht im deutschen Alphabet der Buchstabe <em>\u00d6<\/em> zwischen <em>O<\/em> und <em>P<\/em>, und in der Kodierung <em>CP850<\/em> liegt er zwischen <em>\u00ff<\/em> und <em>\u00dc.<\/em>.<\/p>\n<p><\/p>\n<p>Man kann versuchen, sich von einer bestimmten Kodierung zu abstrahieren und &quot;ideale&quot; Buchstaben, die in einer bestimmten Reihenfolge angeordnet sind, wie in Unicode, zu betrachten. Kodierungen <em>UTF8<\/em>, <em>UTF16<\/em> oder die Ein-Byte-Kodierung <em>KOI8-R<\/em> (wenn eine begrenzte Teilmenge von Unicode erforderlich ist), geben unterschiedliche numerische Darstellungen der Buchstaben, beziehen sich jedoch auf dieselben Elemente der Basistabelle. <\/p>\n<p><\/p>\n<p>Es stellt sich heraus, dass wir selbst, wenn wir eine Zeichentabelle von Grund auf neu erstellen, keine universelle Reihenfolge der Zeichen festlegen k\u00f6nnen. In verschiedenen nationalen Alphabeten, die die gleichen Buchstaben verwenden, kann die Reihenfolge dieser Buchstaben unterschiedlich sein. Zum Beispiel im Franz\u00f6sischen, <em>\u00c6<\/em> wird als Ligatur betrachtet und wie eine Zeichenfolge sortiert <em>AE<\/em>. Im Norwegischen hingegen <em>\u00c6<\/em> wird als eigenst\u00e4ndiger Buchstabe betrachtet, der nach <em>Z<\/em>kommt. \u00dcbrigens gibt es neben Ligaturen wie <em>\u00c6<\/em> auch Buchstaben, die aus mehreren Zeichen bestehen. Im Tschechischen Alphabet gibt es den Buchstaben <em>Ch<\/em>, der zwischen <em>H<\/em> und <em>I<\/em>.<\/p>\n<p><\/p>\n<p>Zu den Unterschieden zwischen den Alphabeten gibt es weitere nationale Traditionen, die die Sortierung beeinflussen. Insbesondere stellt sich die Frage: In welcher Reihenfolge sollten W\u00f6rter in einem W\u00f6rterbuch angeordnet werden, die aus Gro\u00df- und Kleinbuchstaben bestehen? Auch die Verwendung von Satzzeichen kann die Sortierung beeinflussen. Im Spanischen wird am Anfang eines Fragesatzes ein umgedrehter Fragezeichen gesetzt (<em>\u00bfTe gusta la m\u00fasica?<\/em>). In diesem Fall ist es offensichtlich, dass Frage-S\u00e4tze nicht in einem separaten Cluster au\u00dferhalb des Alphabets gruppiert werden sollten, sondern wie sortiert man Zeichenfolgen mit anderen Satzzeichen?<\/p>\n<p><\/p>\n<p>Ich werde nicht auf die Sortierung von Zeichenfolgen in Sprachen eingehen, die sich stark von europ\u00e4ischen unterscheiden. Ich m\u00f6chte darauf hinweisen, dass Zeichen in Sprachen mit einer Schreibrichtung von rechts nach links oder von oben nach unten wahrscheinlich in der Lese-Reihenfolge gespeichert sind, und sogar in nicht-alphabetischen Schriften gibt es eigene M\u00f6glichkeiten, Zeichenfolgen zeichenweise zu ordnen. Beispielsweise k\u00f6nnen Schriftzeichen nach ihrer Form (<noindex><a rel=\"nofollow\" href=\"https:\/\/studychinese.ru\/kljuchi\/\">Schl\u00fcssel von chinesischen Zeichen<\/a><\/noindex>) oder nach ihrer Aussprache sortiert werden. Wie Emojis sortiert werden sollten, kann ich mir ehrlich gesagt nicht vorstellen, aber auch daf\u00fcr kann man sich etwas \u00fcberlegen.<\/p>\n<p><\/p>\n<p>Auf der Grundlage der oben genannten Merkmale wurden die grundlegenden Anforderungen an den Vergleich von Zeichenfolgen, die auf Unicode-Tabellen basieren, formuliert:<\/p>\n<p><\/p>\n<ul>\n<li>Der Vergleich von Zeichenfolgen h\u00e4ngt nicht von der Position der Zeichen in der Codierungstabelle ab;<\/li>\n<li>Zeichenfolgen, die ein einzelnes Zeichen bilden, werden in eine kanonische Form gebracht (<em>A<\/em> + oberer Kreis ist das gleiche wie <em>\u00c5<\/em>);<\/li>\n<li>); beim Vergleich von Zeichenfolgen wird das Zeichen im Kontext der Zeichenfolge betrachtet und, wenn n\u00f6tig, mit Nachbarn zu einer Vergleichseinheit zusammengef\u00fcgt (<em>Ch<\/em> im Tschechischen) oder in mehrere (<em>\u00c6<\/em> im Franz\u00f6sischen);<\/li>\n<li>Alle nationalen Besonderheiten (Alphabete, Gro\u00df-\/Kleinbuchstaben, Satzzeichen, Reihenfolge der Schriftarten) m\u00fcssen bis hin zur manuellen Festlegung der Reihenfolge (Emojis) konfiguriert werden;<\/li>\n<li>Der Vergleich ist nicht nur f\u00fcr die Sortierung wichtig, sondern auch an vielen anderen Stellen, zum Beispiel um Bereichszeilen festzulegen (Ersatz {A\u2026\u044f} in <em>bash<\/em>);<\/li>\n<li>Der Vergleich muss schnell genug durchgef\u00fchrt werden.<\/li>\n<\/ul>\n<p><\/p>\n<p>Dar\u00fcber hinaus haben die Autoren des Berichts Eigenschaften des Vergleichs formuliert, auf die Entwickler des Algorithmus nicht vertrauen sollten:<\/p>\n<p><\/p>\n<ul>\n<li>Der Vergleichsalgorithmus darf nicht einen separaten Zeichensatz f\u00fcr jede Sprache erfordern (Russisch und Ukrainisch verwenden gemeinsam die meisten Zeichen des kyrillischen Alphabets);<\/li>\n<li>Der Vergleich darf nicht auf der Reihenfolge der Zeichen in Unicode-Tabellen basieren;<\/li>\n<li>Das Gewicht einer Zeichenkette darf kein Attribut des Strings sein, da dieselbe Zeichenkette in verschiedenen kulturellen Kontexten unterschiedliche Gewichte haben kann;<\/li>\n<li>Die Gewichte von Strings k\u00f6nnen sich beim Zusammenf\u00fchren oder Teilen \u00e4ndern (aus <em>x<\/em> &lt; <em>y<\/em> Das bedeutet nicht, dass <em>xz<\/em> &lt; <em>yz<\/em>);<\/li>\n<li>Verschiedene Strings, die das gleiche Gewicht haben, gelten aus Sicht des Sortieralgorithmus als gleich. Eine zus\u00e4tzliche Ordnung solcher Strings kann m\u00f6glich sein, k\u00f6nnte jedoch die Leistung verschlechtern;<\/li>\n<li>Bei wiederholten Sortierungen k\u00f6nnen Strings mit dem gleichen Gewicht die Pl\u00e4tze tauschen. Stabilit\u00e4t ist eine Eigenschaft eines bestimmten Sortieralgorithmus, nicht eine Eigenschaft des Vergleichsalgorithmus (siehe vorheriger Punkt);<\/li>\n<li>Die Sortierregeln k\u00f6nnen sich im Laufe der Zeit \u00e4ndern, w\u00e4hrend die kulturellen Traditionen pr\u00e4zisiert oder ge\u00e4ndert werden.<\/li>\n<\/ul>\n<p><\/p>\n<p>Es wird auch klargestellt, dass der Vergleichsalgorithmus nichts \u00fcber die Semantik der verarbeiteten Strings wei\u00df. So sollten Strings, die nur aus Ziffern bestehen, nicht wie Zahlen verglichen werden, und in Listen englischer Bezeichnungen sollte der Artikel nicht entfernt werden (<em>Beatles, The<\/em>).<\/p>\n<p><\/p>\n<p>Um all diesen Anforderungen gerecht zu werden, wurde ein mehrstufiger (tats\u00e4chlich vierstufiger) Tabellen-Sortieralgorithmus vorgeschlagen.<\/p>\n<p><\/p>\n<p>Zun\u00e4chst werden die Zeichen in der Zeichenkette in ihre kanonische Form gebracht und in Vergleichseinheiten gruppiert. Jede Vergleichseinheit erh\u00e4lt mehrere Gewichte, die verschiedenen Vergleichsebenen entsprechen. Die Gewichte der Vergleichseinheiten sind Elemente geordneter Mengen (in diesem Fall ganze Zahlen), die auf Gr\u00f6\u00dfer-Kleiner verglichen werden k\u00f6nnen. Ein spezieller Wert <em>IGNORED<\/em> (0x0) bedeutet, dass diese Einheit auf der entsprechenden Vergleichsebene nicht an dem Vergleich teilnimmt. Der Vergleich von Zeichenfolgen kann mehrmals wiederholt werden, wobei die Gewichte der entsprechenden Ebenen verwendet werden. Auf jeder der Ebenen werden die Gewichte der Vergleichseinheiten zweier Zeichenfolgen nacheinander miteinander verglichen.<\/p>\n<p><\/p>\n<p>In verschiedenen Implementierungen des Algorithmus f\u00fcr verschiedene nationale Traditionen k\u00f6nnen die Werte der Koeffizienten unterschiedlich sein, aber im Standard von Unicode ist eine Basistabelle mit Gewichten enthalten \u2014 <em>&quot;Default Unicode Collation Element Table&quot;<\/em> (<em>DUCET<\/em>). Ich m\u00f6chte bemerken, dass die Festlegung der Variablen <em>LC_COLLATE<\/em> tats\u00e4chlich einen Hinweis auf die Auswahl der Gewichtstabelle in der Funktion zum Vergleich von Zeichenfolgen darstellt.<\/p>\n<p><\/p>\n<p>Die Gewichtskoeffizienten <em>DUCET<\/em> sind wie folgt strukturiert:<\/p>\n<p><\/p>\n<ul>\n<li>Auf der ersten Ebene werden alle Buchstaben in dieselbe Gro\u00df- und Kleinschreibung umgewandelt, diakritische Zeichen werden verworfen, Satzzeichen (nicht alle) werden ignoriert;<\/li>\n<li>Auf der zweiten Ebene werden nur diakritische Zeichen ber\u00fccksichtigt;<\/li>\n<li>Auf der dritten Ebene wird nur die Gro\u00df- und Kleinschreibung ber\u00fccksichtigt;<\/li>\n<li>Auf der vierten Ebene werden nur Satzzeichen ber\u00fccksichtigt.<\/li>\n<\/ul>\n<p><\/p>\n<p>Der Vergleich erfolgt in mehreren Durchg\u00e4ngen: Zun\u00e4chst werden die Koeffizienten der ersten Ebene verglichen; wenn die Gewichte \u00fcbereinstimmen, erfolgt ein erneuter Vergleich mit den Gewichten der zweiten Ebene; danach m\u00f6glicherweise mit der dritten und vierten.<\/p>\n<p><\/p>\n<p>Der Vergleich endet, wenn in den Zeichenfolgen \u00fcbereinstimmende Vergleichseinheiten mit unterschiedlichen Gewichten gefunden werden. Zeichenfolgen, die auf allen vier Ebenen gleiche Gewichte haben, werden als gleich angesehen.<\/p>\n<p><\/p>\n<p>Dieser Algorithmus (mit einer Menge zus\u00e4tzlicher technischer Details) gab dem Bericht Nr. 10 \u2014 <em>&quot;Unicode Collation Algorithm&quot;<\/em> (<em>UCA<\/em>).<\/p>\n<p><\/p>\n<p>An dieser Stelle wird das Sortierverhalten aus unserem Beispiel etwas verst\u00e4ndlicher. Es w\u00e4re gut, es mit dem Unicode-Standard zu vergleichen.<\/p>\n<p><\/p>\n<p>F\u00fcr die Testung von Implementierungen <em>UCA<\/em> gibt es einen speziellen <noindex><a rel=\"nofollow\" href=\"https:\/\/www.unicode.org\/Public\/UCA\/latest\/CollationTest.html\">Test<\/a><\/noindex>, der eine <noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">Gewichtstabelle<\/a><\/noindex>, die implementiert <em>DUCET<\/em>verwendet. In der Gewichtstabelle k\u00f6nnen verschiedene Kuriosit\u00e4ten gefunden werden. Zum Beispiel gibt es dort die Reihenfolge der Spielsteine von Mahjong und dem europ\u00e4ischen Domino sowie die Reihenfolge der Farben in einem Kartenspiel (Symbol <em>1F000<\/em> und weiter). Die Kartensuiten sind gem\u00e4\u00df den Regeln des Bridge angeordnet \u2014 PIK, KREUZ, HERZ, KARO, und die Karten in der Suite \u2014 in der Reihenfolge 10, 2, 3\u2026 K.<\/p>\n<p><\/p>\n<p>Eine manuelle \u00dcberpr\u00fcfung der Richtigkeit der Sortierung von Zeichenfolgen gem\u00e4\u00df <em>DUCET<\/em> w\u00e4re ziemlich m\u00fchsam, aber gl\u00fccklicherweise gibt es eine vorbildliche Implementierung einer Bibliothek zur Arbeit mit Unicode \u2014 &quot;<noindex><a rel=\"nofollow\" href=\"http:\/\/site.icu-project.org\/\">Internationale Komponenten f\u00fcr Unicode<\/a><\/noindex>&quot; (<em>ICU<\/em>).<\/p>\n<p><\/p>\n<p>Auf der Website dieser Bibliothek, die in <em>IBM<\/em>, gibt es Demoseiten, einschlie\u00dflich <noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">einer Seite mit dem Algorithmus zum Vergleichen von Zeichenfolgen<\/a><\/noindex>. Wir geben unsere Teststrings mit den Standardeinstellungen ein und, oh Wunder, erhalten eine perfekte russische Sortierung.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Abakanov Michail;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanov Andrei;Schlosser\nIvanova Alla;Rechtsanw\u00e4ltin<\/code><\/pre>\n<p><\/p>\n<p>\u00dcbrigens, auf der Website <em>ICU<\/em> kann man eine Erl\u00e4uterung der Arbeitsweise des Vergleichsalgorithmus bei der Verarbeitung von Satzzeichen finden. In den Beispielen <noindex><a rel=\"nofollow\" href=\"http:\/\/userguide.icu-project.org\/collation\/faq\">Collation FAQ<\/a><\/noindex> werden Apostroph und Bindestrich ignoriert.<\/p>\n<p><\/p>\n<p>Unicode hat uns geholfen, aber die Ursachen f\u00fcr das merkw\u00fcrdige Verhalten <em>sortieren<\/em> in <em>Linux<\/em> m\u00fcssen wir woanders suchen.<\/p>\n<p><\/p>\n<h1 id=\"sortirovka-v-glibc\">Sortierung in glibc<\/h1>\n<p><\/p>\n<p>Ein kurzer Blick auf den Quellcode des Dienstprogramms <em>sortieren<\/em> aus <em>GNU Core Utils<\/em> zeigte, dass die Lokalisierung in dem Dienstprogramm sich auf das Drucken des aktuellen Wertes der Variablen beschr\u00e4nkt <em>LC_COLLATE<\/em> im Debug-Modus beim Start:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ sort --debug buhg.txt &gt; buhg.srt\nsort: verwendet die Sortierregeln von \u201aen_US.UTF8\u2018<\/code><\/pre>\n<p><\/p>\n<p>Der Vergleich von Zeichenfolgen erfolgt durch die Standardfunktion <em>strcoll<\/em>, was bedeutet, dass alles Interessante in der Bibliothek <em>glibc<\/em>.<\/p>\n<p><\/p>\n<p>Auf <em>wiki<\/em> des Projekts <em>glibc<\/em> f\u00fcr den Vergleich von Zeichenfolgen gewidmet ist, <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/glibc\/wiki\/Locales#LC_COLLATE\">einem Absatz<\/a><\/noindex>. Aus diesem Absatz kann man verstehen, dass in der <em>glibc<\/em> die Sortierung auf dem uns bereits bekannten Algorithmus basiert <em>UCA<\/em> (<em>Der Unicode-Sortieralgorithmus<\/em>) und\/oder auf einem \u00e4hnlichen Standard <em>ISO 14651<\/em> (<em>Internationale Zeichenreihenfolge und Vergleich<\/em>). Zum letzten Standard sollte angemerkt werden, dass er auf der Website <noindex><a rel=\"nofollow\" href=\"https:\/\/standards.iso.org\/ittf\/PubliclyAvailableStandards\">standards.iso.org<\/a><\/noindex> <em>ISO 14651<\/em> offiziell als \u00f6ffentlich zug\u00e4nglich erkl\u00e4rt wurde, der entsprechende Link jedoch auf eine nicht existierende Seite f\u00fchrt. Google zeigt mehrere Seiten mit Links zu offiziellen Websites, die anbieten, eine elektronische Kopie des Standards f\u00fcr ein paar Hundert Euro zu kaufen, aber auf der dritten oder vierten Seite der Google-Suche findet man auch direkte Links zu <em>PDF<\/em>. Insgesamt weicht der Standard kaum von <em>UCA<\/em>, ab, wird jedoch langweiliger gelesen, da er keine anschaulichen Beispiele f\u00fcr nationale Besonderheiten der Sortierung von Zeichenfolgen enth\u00e4lt. <\/p>\n<p><\/p>\n<p>Die interessanteste Information auf <em>wiki<\/em> war der Link zu <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=14095\">Bug-Tracker<\/a><\/noindex> mit einer Diskussion \u00fcber die Implementierung des Zeichenfolgenvergleichs in <em>glibc<\/em>. Aus der Diskussion kann man erfahren, dass in <em>glibc<\/em> f\u00fcr den Vergleich von Zeichenfolgen eine <em>ISO<\/em>Tabelle verwendet wird <noindex><a rel=\"nofollow\" href=\"http:\/\/www.iso.org\/ittf\/ISO14651_2006_TABLE1_en.txt\">Die gemeinsame Vorlagentabelle<\/a><\/noindex> (<em>CTT<\/em>), deren Adresse im Anhang zu finden ist <em>A<\/em> des Standards <em>ISO 14651<\/em>. Zwischen 2000 und 2015 wurde diese Tabelle in <em>glibc<\/em> hat keinen Maintainer gehabt und unterschied sich (zumindest \u00e4u\u00dferlich) erheblich von der aktuellen Version des Standards. Von 2015 bis 2018 fand eine Anpassung an die neue Version der Tabelle statt und derzeit haben Sie die M\u00f6glichkeit, sowohl die neue Version der Tabelle (<em>CentOS 8<\/em>), als auch die alte zu begegnen (<em>CentOS 7<\/em>). <\/p>\n<p><\/p>\n<p>Jetzt, da wir alle Informationen \u00fcber den Algorithmus und die Hilfstabellen haben, k\u00f6nnen wir zur urspr\u00fcnglichen Problematik zur\u00fcckkehren und verstehen, wie man die Zeilen in der russischen Locale richtig sortiert.<\/p>\n<p><\/p>\n<h1 id=\"iso-1465114652\">ISO 14651\/14652<\/h1>\n<p><\/p>\n<p>Der Quellcode der betreffenden Tabelle <em>CTT<\/em> findet sich in den meisten Distributionen <em>Linux<\/em> im Verzeichnis <em>\/usr\/share\/i18n\/locales\/<\/em>. Die Tabelle selbst befindet sich in der Datei <em>iso14651_t1_common<\/em>. Diese Datei wird dann mit der Direktive <em>copy iso14651_t1_common<\/em> in die Datei <em>iso14651_t1<\/em>, die ihrerseits in die nationalen Dateien eingebunden wird, einschlie\u00dflich <em>en_US<\/em> und <em>ru_RU<\/em>. In den meisten Distributionen <em>Linux<\/em> sind alle Quelldateien im Basispaket enthalten, aber wenn sie nicht vorhanden sind, m\u00fcssen Sie ein zus\u00e4tzliches Paket aus der Distribution installieren.<\/p>\n<p><\/p>\n<p>Dateistruktur <em>iso14651_t1<\/em> mag furchtbar wortreich erscheinen, mit nicht offensichtlichen Regeln zur Namensbildung, aber wenn man sich damit besch\u00e4ftigt, ist alles ziemlich einfach. Die Struktur ist im Standard <em>ISO 14652<\/em>beschrieben, eine Kopie davon kann von der Website <noindex><a rel=\"nofollow\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG20\/docs\/n972-14652ft.pdf\">open-std.org<\/a><\/noindex>heruntergeladen werden. Eine weitere Beschreibung des Dateiformats kann in den <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/basedefs\/V1_chap07.html\">Spezifikationen<\/a><\/noindex> <em>POSIX<\/em> ab <em>OpenGroup<\/em>gelesen werden. Als Alternative zum Lesen des Standards kann man die Quelltexte der Funktion <em>collate_read<\/em> in <em>glibc\/locale\/programs\/ld-collate.c<\/em>.<\/p>\n<p><\/p>\n<p>Die Struktur der Datei sieht folgenderma\u00dfen aus:<\/p>\n<p><\/p>\n<p>Standardm\u00e4\u00dfig wird das Symbol  als Escape-Zeichen verwendet, und das Ende einer Zeile nach dem Symbol # ist ein Kommentar. Beide Zeichen k\u00f6nnen \u00fcberschrieben werden, was in der neuen Version der Tabelle auch geschehen ist:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">escape_char \/\ncomment_char %<\/code><\/pre>\n<p><\/p>\n<p>In der Datei werden Token im Format <em>&lt;Uxxxx&gt;<\/em> oder <em>&lt;Uxxxxxxxx&gt;<\/em> (wo <em>x<\/em> \u2014 hexadezimale Ziffer). Dies ist die hexadezimale Darstellung von Unicode-Codepunkten in der Kodierung <em>UCS-4<\/em> (<em>UTF-32<\/em>). Alle anderen Elemente in spitzen Klammern (einschlie\u00dflich <em>&lt;Uxxxx_xxxx&gt;<\/em>, <em>&lt;2&gt;<\/em> und \u00e4hnliche) gelten als einfache Zeichenkonstanten, die au\u00dferhalb des Kontexts keine besondere Bedeutung haben.<\/p>\n<p><\/p>\n<p>Zeichenkette <em>LC_COLLATE<\/em> sagt uns, dass im Folgenden die Daten beginnen, die den Vergleich von Zeichenfolgen beschreiben.<\/p>\n<p><\/p>\n<p>Zun\u00e4chst werden Namen f\u00fcr die Gewichte in der Vergleichstabelle und Namen f\u00fcr die Kombinationen von Zeichen festgelegt. Im Allgemeinen geh\u00f6ren zwei Arten von Namen zu zwei verschiedenen Entit\u00e4ten, aber in der tats\u00e4chlichen Datei sind sie vermischt. Die Gewichtsbezeichner werden mit dem Schl\u00fcsselwort <em>collating-symbol<\/em> (Vergleichssymbol), da Unicode-Zeichen mit gleichen Gewichten als \u00e4quivalente Symbole betrachtet werden.<\/p>\n<p><\/p>\n<p>Die Gesamtl\u00e4nge des Abschnitts in der aktuellen Revision der Datei betr\u00e4gt etwa 900 Zeilen. Ich habe Beispiele aus verschiedenen Quellen gesammelt, um die Beliebigkeit der Namen und einige Arten der Syntax zu veranschaulichen.<\/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; % Garantierter gr\u00f6\u00dfter Symbolwert. Am Ende dieser Liste belassen\n...\ncollating-element &lt;U0413_0301&gt; von &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;\ncollating-element &lt;U0413_0341&gt; von &quot;&lt;U0413&gt;&lt;U0341&gt;&quot;<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><em>collating-symbol<\/em> registriert die Zeichenkette <em>OSMANYA<\/em> in der Gewichtsnamentabelle <\/li>\n<li><em>collating-symbol ..<\/em> registriert eine Sequenz von Namen, die aus einem Pr\u00e4fix bestehen <em>S<\/em> und einem hexadezimalen Zahlensuffix von <em>1D000<\/em> bis <em>1D35F<\/em>.<\/li>\n<li><em>FFFF<\/em> in <em>collating-symbol<\/em> sieht aus wie eine gro\u00dfe nicht-negative ganze Zahl im hexadezimalen Zahlensystem, aber <em>&lt;SFFFF&gt;<\/em> ist einfach ein Name, der aussehen k\u00f6nnte wie <em>&lt;VERYBIGVAL&gt;<\/em> <\/li>\n<li>name <em>&lt;U0413&gt;<\/em> steht f\u00fcr den Codepunkt im Encoding <em>UCS-4<\/em><\/li>\n<li><em>collating-element &lt;U0413_0301&gt; von &quot;&lt;U0413&gt;&lt;U0301&gt;&quot;<\/em> registriert einen neuen Namen f\u00fcr ein Paar von Unicode-Punkten. <\/li>\n<\/ul>\n<p><\/p>\n<p>Wenn die Gewichtsbezeichnungen definiert sind, werden die Gewichte selbst festgelegt. Da nur die Beziehungen gr\u00f6\u00dfer-kleiner beim Vergleich wichtig sind, werden die Gewichte in einer einfachen Reihenfolge der Benennung festgelegt. Zuerst werden die &quot;leichteren&quot; Gewichte aufgef\u00fchrt, dann die &quot;schwereren&quot;. Ich erinnere daran, dass jedem Unicode-Zeichen vier unterschiedliche Gewichte zugeordnet werden. Hier sind sie in eine einheitliche sortierte Reihenfolge gebracht. Theoretisch kann jeder symbolische Name auf jeder der vier Ebenen verwendet werden, aber die Kommentare deuten darauf hin, dass die Entwickler die Namen mental nach Ebenen unterscheiden.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">% Symbolische Gewichtszuweisungen\n\n% Gewichtszuweisungen der dritten Ebene\n\n\n\n\n...\n% Gewichtszuweisungen der zweiten Ebene\n\n % KOMBINIERENDE UNTERLINIE\n % KOMBINIERENDE KOMMA OBEN\n % KOMBINIERENDE UMGEKEHRTE KOMMA OBEN\n...\n% Gewichtszuweisungen der ersten Ebene\n % HORIZONTALE TABULIERUNG\n % ZEILENWECHSEL\n % VERTIKALE TABULIERUNG\n...\n % KIRILLESCHES KLEINES BUCHSTABEN DE\n % KIRILLESCHES KLEINES BUCHSTABEN KOMI DE\n % KIRILLESCHES KLEINES BUCHSTABEN DJE\n % KIRILLESCHES KLEINES BUCHSTABEN KOMI DJE\n % KIRILLESCHES KLEINES BUCHSTABEN GJE\n % KIRILLESCHES KLEINES BUCHSTABEN ZE MIT DESCENDER\n % KIRILLESCHES KLEINES BUCHSTABEN IE\n % KIRILLESCHES KLEINES BUCHSTABEN IE MIT BREVE\n % KIRILLESCHES KLEINES BUCHSTABEN UKRAINISCHES IE\n % KIRILLESCHES KLEINES BUCHSTABEN ZHE<\/code><\/pre>\n<p><\/p>\n<p>Endlich die eigentliche Gewichtstabelle.<\/p>\n<p><\/p>\n<p>Der Abschnitt der Gewichte ist in Zeilen mit Schl\u00fcsselw\u00f6rtern eingeschlossen <em>order_start<\/em> und <em>order_end<\/em>. Zus\u00e4tzliche Parameter <em>order_start<\/em> legen fest, in welcher Richtung die Zeilen auf jeder Vergleichsebene durchsucht werden. Standardm\u00e4\u00dfig wird der Parameter verwendet <em>forward<\/em>. Der Inhalt des Abschnitts besteht aus Zeilen, die den Zeichen-Code und vier Gewichtungen enthalten. Der Zeichen-Code kann entweder durch das Zeichen selbst, den Codepunkt oder den zuvor definierten symbolischen Namen dargestellt werden. Die Gewichtungen k\u00f6nnen ebenfalls durch symbolische Namen, Codepunkte oder die Zeichen selbst angegeben werden. Wenn Codepunkte oder Zeichen verwendet werden, entspricht ihr Gewicht dem numerischen Wert des Codepunkts (Position in der Unicode-Tabelle). Zeichen, die nicht ausdr\u00fccklich aufgef\u00fchrt sind (so verstehe ich), werden in der Tabelle mit einem Prim\u00e4rgewicht angerechnet, das mit der Position in der Unicode-Tabelle \u00fcbereinstimmt. Der besondere Gewichtswert <em>IGNORE<\/em> bedeutet, dass das entsprechende Zeichen auf dieser Vergleichsebene ignoriert wird.<\/p>\n<p><\/p>\n<p>Um die Struktur der Gewichte zu demonstrieren, habe ich drei recht offensichtliche Fragmente ausgew\u00e4hlt:<\/p>\n<p><\/p>\n<ul>\n<li>Zeichen, die vollst\u00e4ndig ignoriert werden<\/li>\n<li>Zeichen, die auf den ersten beiden Ebenen der Ziffer drei entsprechen<\/li>\n<li>der Anfang des kyrillischen Alphabets, der keine diakritischen Zeichen enth\u00e4lt und daher haupts\u00e4chlich nach der ersten und dritten Ebene sortiert wird.<\/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 ;;; % ZIFFER DREI\n ;;; % VOLLSCHRIFT ZIFFER DREI\n ;;; % KLAUSE ZIFFER DREI\n ;;; % ZIFFER DREI PUNKT\n ;;<FONT>; % MATHEMATISCH FETT ZIFFER DREI\n...\n ;;; % KYRILLESCH KLEINBUCHSTABE A\n ;;; % KYRILLESCH GROSSBUCHSTABE A\n ;;; % KYRILLESCH KLEINBUCHSTABE A MIT BREVE\n ;;; % KYRILLESCH KLEINBUCHSTABE A MIT BREVE\n...\n ;;; % KYRILLESCH KLEINBUCHSTABE BE\n ;;; % KYRILLESCH GROSSBUCHSTABE BE\n ;;; % KYRILLESCH KLEINBUCHSTABE VE\n ;;; % KYRILLESCH GROSSBUCHSTABE VE\n...\norder_end<\/code><\/pre>\n<p><\/p>\n<p>Jetzt k\u00f6nnen wir zu den Beispielen aus dem Anfang des Artikels zur\u00fcckkehren. Die Falle steckt in diesem Teil der Gewichtstabelle:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">IGNORIERE;IGNORIERE;IGNORIERE; % R\u00c4UME\n IGNORIERE;IGNORIERE;IGNORIERE; % AUSRUFEZEICHEN\n IGNORIERE;IGNORIERE;IGNORIERE; % ANF\u00dcHRUNGSZEICHEN\n...<\/code><\/pre>\n<p><\/p>\n<p>Es ist offensichtlich, dass in dieser Tabelle die Interpunktion aus der Tabelle stammt. <em>ASCII<\/em> (einschlie\u00dflich Leerzeichen) wird beim Vergleich von Zeichenfolgen praktisch immer ignoriert. Die Ausnahme bilden nur Zeichenfolgen, die in allem \u00fcbereinstimmen, au\u00dfer in der Interpunktion, die an \u00fcbereinstimmenden Positionen vorkommt. Die Zeichenfolgen aus meinem Beispiel (nach der Sortierung) sehen f\u00fcr den Vergleichsalgorithmus so aus:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">AbakanovMikhailMaler\nJolkinaEllegardistin\nIvanovaAllaMalerin\nIvanovAndreiZimmermann<\/code><\/pre>\n<p><\/p>\n<p>Da in der Gewichtstabelle Gro\u00dfbuchstaben im Russischen nach den Kleinbuchstaben kommen (auf der dritten Ebene <em>&lt;CAP&gt;<\/em> schwerer als <em>&lt;MIN&gt;<\/em>), sieht die Sortierung absolut korrekt aus.<\/p>\n<p><\/p>\n<p>Bei der Festlegung der Variablen <em>LC_COLLATE=C<\/em> wird eine spezielle Tabelle geladen, die byteweise Vergleiche festlegt.<\/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 im Unicode der Codepunkt \u0401 vor \u0410 steht, werden die Zeichenfolgen entsprechend sortiert.<\/p>\n<p><\/p>\n<h1 id=\"tekstovye-i-dvoichnye-tablicy\">Text- und Bin\u00e4rdatenbanken<\/h1>\n<p><\/p>\n<p>Offensichtlich ist der Vergleich von Zeichenfolgen eine \u00e4u\u00dferst h\u00e4ufige Operation, w\u00e4hrend das Parsen der Tabelle <em>CTT<\/em> eine ziemlich aufw\u00e4ndige Prozedur ist. Zur Optimierung des Zugriffs auf die Tabelle wird sie mit dem Befehl <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Team <em>localedef<\/em> so konfiguriert, dass sie als Parameter eine Datei mit der Tabelle der nationalen Besonderheiten (Option <em>-i<\/em>), in der alle Zeichen durch Unicode-Punkten dargestellt werden, und eine Datei mit der Zuordnung der Unicode-Punkte zu Zeichen einer bestimmten Kodierung (Option <em>-f<\/em>) erh\u00e4lt. Infolge der Verarbeitung werden Bin\u00e4rdateien f\u00fcr die Locale mit dem im letzten Parameter angegebenen Namen erstellt.<\/p>\n<p><\/p>\n<p><em>Glibc<\/em> unterst\u00fctzt zwei Formate f\u00fcr Bin\u00e4rdateien: &quot;traditionell&quot; und &quot;modern&quot;.<\/p>\n<p><\/p>\n<p>Das traditionelle Format setzt voraus, dass der Name der Locale der Name eines Unterverzeichnisses in <em>\/usr\/lib\/locale\/<\/em>. In diesem Unterverzeichnis werden die Bin\u00e4rdateien aufbewahrt. <em>LC_COLLATE<\/em>, <em>LC_CTYPE<\/em>, <em>LC_TIME<\/em> usw. Die Datei <em>LC_IDENTIFICATION<\/em> enth\u00e4lt den formalen Namen der Locale (der sich vom Namen des Verzeichnisses unterscheiden kann) und Kommentare.<\/p>\n<p><\/p>\n<p>Das moderne Format sieht vor, dass alle Locales in einem einzigen Archiv gespeichert werden <em>\/usr\/lib\/locale\/locale-archive<\/em>, das in den virtuellen Speicher aller Prozesse abgebildet wird, die es verwenden. <em>glibc<\/em>. Der Name der Locale im modernen Format wird einer gewissen Kanonisierung unterzogen \u2013 in den Kodierungsnamen bleiben nur Ziffern und Buchstaben, die in Kleinbuchstaben konvertiert sind. So <em>ru_RU.KOI8-R<\/em>, wird als <em>ru_RU.koi8r<\/em>.<\/p>\n<p><\/p>\n<p>eingehende Dateien werden im aktuellen Verzeichnis sowie in den Verzeichnissen <em>\/usr\/share\/i18n\/locales\/<\/em> und <em>\/usr\/share\/i18n\/charmaps\/<\/em> f\u00fcr Dateien <em>CTT<\/em> und Kodierungsdateien gesucht.<\/p>\n<p><\/p>\n<p>Zum Beispiel, der Befehl<\/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>kompiliert die Datei <em>\/usr\/share\/i18n\/locales\/ru_RU<\/em> unter Verwendung der Kodierungsdatei <em>\/usr\/share\/i18n\/charmaps\/MAC-CYRILLIC.gz<\/em> und speichert das Ergebnis in <em>\/usr\/lib\/locale\/locale-archive<\/em> unter dem Namen <em>ru_RU.maccyrillic<\/em><\/p>\n<p><\/p>\n<p>Wenn die Variable <em>LANG=en_US.UTF-8<\/em> gesetzt ist, <em>glibc<\/em> wird nach bin\u00e4ren Locale-Dateien in der folgenden Reihenfolge von Dateien und Verzeichnissen gesucht:<\/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>Wenn die Locale sowohl im traditionellen als auch im modernen Format vorhanden ist, hat das moderne Format Vorrang.<\/p>\n<p><\/p>\n<p>Eine Liste der kompilierten Locales kann mit dem Befehl <em>locale -a<\/em>.<\/p>\n<p><\/p>\n<h1 id=\"podgotovka-svoey-tablicy-sravneniya\">eingesehen werden.<\/h1>\n<p><\/p>\n<p>Erstellung einer eigenen Sortiertabelle <em>ASCII<\/em>.<\/p>\n<p><\/p>\n<p>Jetzt, ger\u00fcstet mit dem Wissen, kann man eine eigene ideale Vergleichstabelle von Zeichen erstellen. Diese Tabelle sollte russische Buchstaben korrekt vergleichen, einschlie\u00dflich des Buchstabens \u0401, und dabei die Interpunktion gem\u00e4\u00df der Tabelle ber\u00fccksichtigen. <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Der Prozess der Erstellung der eigenen Sortiertabelle besteht aus zwei Phasen: der Bearbeitung der Gewichtungstabelle und ihrer Kompilierung in eine bin\u00e4re Form mit dem Befehl <em>ISO 14652<\/em> Um die Vergleichstabelle mit minimalen Bearbeitungskosten anzupassen, sieht das Format <em>Abschnitte zur Anpassung der Gewichtung einer bereits bestehenden Tabelle vor. Der Abschnitt beginnt mit dem Schl\u00fcsselwort<\/em> reorder-after <em>und der Angabe der Position, nach der die Ersetzung erfolgt. Der Abschnitt endet mit der Zeile<\/em>. Wenn mehrere Teile der Tabelle angepasst werden m\u00fcssen, wird f\u00fcr jeden Teil ein eigener Abschnitt erstellt.<\/p>\n<p><\/p>\n<p>Ich habe die neuen Versionen der Dateien <em>iso14651_t1_common<\/em> und <em>ru_RU<\/em> aus dem Repository <em>glibc<\/em> in mein Heimatverzeichnis ~\\\/local\\\/share\\\/i18n\\\/locales\\\/ kopiert und den Abschnitt leicht bearbeitet. <em>LC_COLLATE<\/em> in <em>ru_RU<\/em>Die neuen Versionen der Dateien sind vollst\u00e4ndig kompatibel mit meiner Version. <em>glibc<\/em>Wenn Sie die alten Versionen der Dateien verwenden m\u00f6chten, m\u00fcssen Sie die symbolischen Namen \u00e4ndern und den Ort anpassen, an dem der Austausch in der Tabelle beginnt.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">LC_COLLATE\n% Kopiere die Vorlage von 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; % AUSRUFEZEICHEN\n&lt;U0022&gt; &lt;S0022&gt;;&lt;BASE&gt;&lt;MIN&gt;&lt;U0022&gt; % ANF\u00dcHRUNGSZEICHEN\n...\n&lt;U007D&gt; &lt;S007D&gt;;&lt;BASE&gt;&lt;MIN&gt;&lt;U007D&gt; % RECHTE GARDINENKLAMMER\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>Tats\u00e4chlich h\u00e4tte man die Felder in <em>LC_IDENTIFICATION<\/em> so \u00e4ndern m\u00fcssen, dass sie auf die Locale <em>ru_MY<\/em>verweisen, aber in meinem Beispiel war das nicht n\u00f6tig, da ich die Locales aus dem Suchearchiv ausgeschlossene <em>locale-archive<\/em>.<\/p>\n<p><\/p>\n<p>Um <em>localedef<\/em> mit den Dateien in meinem Ordner \u00fcber die Variable <em>I18NPATH<\/em> kann ein zus\u00e4tzliches Verzeichnis zur Suche nach Eingabedateien hinzugef\u00fcgt werden, w\u00e4hrend das Verzeichnis zum Speichern der Bin\u00e4rdateien als Pfad mit Schr\u00e4gstrichen angegeben werden kann:<\/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> geht davon aus, dass in <em>LANG<\/em> absolute Pfade zu den Verzeichnissen mit den Locale-Dateien, die mit einem Schr\u00e4gstrich beginnen, angegeben werden k\u00f6nnen, aber <em>glibc<\/em> in <em>Linux<\/em> alle Pfade von dem Basisverzeichnis ausgehen, das \u00fcber die Variable <em>LOCPATH<\/em>\u00fcberschrieben werden kann. Nach der Festlegung von <em>LOCPATH=~\/.local\/lib\/locale\/<\/em> werden alle mit der Lokalisierung verbundenen Dateien nur in meinem Ordner gesucht. Das Archiv der Locales, wenn die Variable gesetzt ist, <em>LOCPATH<\/em> werden ignoriert.<\/p>\n<p><\/p>\n<p>Hier ist der entscheidende Test:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=ru_MY.UTF-8 LOCPATH=~\/.local\/lib\/locale\/ sort buhg.txt\nAbakanow Michail;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanow Andrej;Schlosser\nIvanowa Alla;Rechtsanw\u00e4ltin<\/code><\/pre>\n<p><\/p>\n<p>Hurra! Wir haben es geschafft!<\/p>\n<p><\/p>\n<h1 id=\"rabota-nad-oshibkami\">Arbeiten an Fehlern<\/h1>\n<p><\/p>\n<p>Ich habe bereits die Fragen zur Sortierung der Zeilen, die zu Beginn gestellt wurden, beantwortet, aber es bleiben noch ein paar Fragen zu Fehlern \u2013 sichtbaren und unsichtbaren.<\/p>\n<p><\/p>\n<p>Lassen Sie uns zur urspr\u00fcnglichen Aufgabe zur\u00fcckkehren.<\/p>\n<p><\/p>\n<p>Und das Programm <em>sortieren<\/em> und das Programm <em>join<\/em> verwendet dieselben Zeichenvergleichsfunktionen aus <em>glibc<\/em>. Wie konnte es also sein, dass <em>join<\/em> einen Sortierfehler bei den von dem Befehl <em>sortieren<\/em> in der Locale <em>en_US.UTF-8<\/em>? \u041e\u0442\u0432\u0435\u0442 \u043f\u0440\u043e\u0441\u0442: <em>sortieren<\/em> verursachte, vergleicht die gesamte Zeichenfolge, w\u00e4hrend <em>join<\/em> nur den Schl\u00fcssel vergleicht, der standardm\u00e4\u00dfig der Anfang der Zeichenfolge bis zum ersten Leerzeichen ist. In meinem Beispiel f\u00fchrte das zu einer Fehlermeldung, da die Sortierung der ersten W\u00f6rter in den Zeilen nicht mit der Sortierung der vollst\u00e4ndigen Zeilen \u00fcbereinstimmte.<\/p>\n<p><\/p>\n<p>Die Locale <em>&quot;C&quot;<\/em> stellt sicher, dass in den sortierten Zeichenfolgen die anf\u00e4nglichen Teilzeichenfolgen bis zum ersten Leerzeichen ebenfalls sortiert sind, aber das maskiert nur den Fehler. Es k\u00f6nnen solche Daten (Menschen mit denselben Nachnamen, aber unterschiedlichen Vornamen) ausgew\u00e4hlt werden, die ohne Fehlermeldung zu einem falschen Ergebnis beim Zusammenf\u00fchren von Dateien f\u00fchren w\u00fcrden. Wenn wir m\u00f6chten, dass <em>join<\/em> Zeilen von Dateien nach vollst\u00e4ndigem Namen (Vorname, Nachname) zusammenf\u00fchrt, dann w\u00e4re der richtige Weg die explizite Angabe des Feldtrennzeichens und die Sortierung nach dem Schl\u00fcssel, anstatt nach der gesamten Zeile. In diesem Fall erfolgt das Zusammenf\u00fchren korrekt und es gibt in keiner Locale Fehler:<\/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>Ein erfolgreich ausgef\u00fchrtes Beispiel in der Kodierung <em>CP1251<\/em> enth\u00e4lt einen weiteren Fehler. Das Problem ist, dass in allen mir bekannten Distributionen <em>Linux<\/em> die kompilierte Locale fehlt <em>ru_RU.CP1251<\/em>. Wenn die kompilierte Locale nicht gefunden wird, <em>sortieren<\/em> verwendet es stillschweigend den byte-by-byte Vergleich, was wir beobachtet haben.<\/p>\n<p><\/p>\n<p>\u00dcbrigens gibt es noch einen kleinen Bug im Zusammenhang mit der Unzug\u00e4nglichkeit der kompilierten Locales. Der Befehl <em>LOCPATH=\\\/tmp locale -a<\/em> gibt eine Liste aller Locales in <em>locale-archive<\/em>, aber mit einer gesetzten Variablen <em>LOCPATH<\/em> sind diese Locales f\u00fcr alle Programme (einschlie\u00dflich <em>locale<\/em>) nicht verf\u00fcgbar.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LOCPATH=\\\/tmp locale -a | grep en_US\nlocale: LC_CTYPE kann nicht auf die Standard-Locale gesetzt werden: Datei oder Verzeichnis nicht gefunden\nlocale: LC_MESSAGES kann nicht auf die Standard-Locale gesetzt werden: Datei oder Verzeichnis nicht gefunden\nlocale: LC_COLLATE kann nicht auf die Standard-Locale gesetzt werden: Datei oder Verzeichnis nicht gefunden\nen_US\nen_US.iso88591\nen_US.iso885915\nen_US.utf8\n\n$&gt; LC_COLLATE=en_US.UTF-8 sort --debug\nsort: verwendet die Sortierregeln von 'en_US.UTF-8'\n\n$&gt; LOCPATH=\\\/tmp LC_COLLATE=en_US.UTF-8 sort --debug\nsort: verwendet den einfachen Byte-Vergleich<\/code><\/pre>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Fazit<\/h1>\n<p><\/p>\n<p>Wenn Sie ein Programmierer sind, der es gewohnt ist zu denken, dass Zeichenfolgen eine Ansammlung von Bytes sind, dann ist Ihre Wahl <em>LC_COLLATE=C<\/em>.<\/p>\n<p><\/p>\n<p>Wenn Sie Linguist oder W\u00f6rterbuchmacher sind, dann sollten Sie Ihre Locale besser kompilieren.<\/p>\n<p><\/p>\n<p>Wenn Sie ein einfacher Benutzer sind, dann sollten Sie sich daran gew\u00f6hnen, dass der Befehl <em>ls -a<\/em> Dateien auflistet, die mit einem Punkt beginnen, vermischt mit Dateien, die mit einem Buchstaben beginnen, und <em>Midnight Commander<\/em>, der seine internen Funktionen zum Sortieren von Namen verwendet, bringt Dateien, die mit einem Punkt beginnen, an den Anfang der Liste.<\/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\/\">Bericht Nr. 10 Unicode-Vergleichsalgorithmus <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">Gewichte der Zeichen auf 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 eine Implementierung der Bibliothek zur Arbeit mit Unicode von IBM. <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">Testsortierung mit <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\">Gewichten der Zeichen in <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\">Beschreibung des Dateiformats mit Gewichten <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 \u00fcber den Vergleich von Zeichenfolgen in <em>glibc<\/em><\/a><\/noindex><\/p>\n<p>Quelle: <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.1.1 - 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\/de\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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\/de\/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\udd47Wie Linux\u2019 sort Befehle Zeichenfolgen sortiert | ProHoster","description":"Einf\u00fchrung Alles begann mit einem kurzen Skript, das die Informationen \u00fcber die E-Mail-Adressen der Mitarbeiter, die aus einer Liste von Mailinglistenbenutzern erhalten wurden, zusammenf\u00fchren sollte, mit.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kak-linuxovskij-sort-sortiruet-stroki","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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\/de\/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\/de\/wp-json\/wp\/v2\/posts\/83055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=83055"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/83055\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=83055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=83055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=83055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}