{"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 sortiert Linux' sort Zeichenfolgen","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 der Liste der Mailinglistenbenutzer stammten, mit den Positionen der Mitarbeiter zu kombinieren, die aus der Datenbank der Personalabteilung gewonnen wurden. 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\nElkina 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 ein Unix-Programm \u00fcbergeben <em>beitreten<\/em>, das unerwartet mit einem Fehler abgebrochen wurde: <\/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 insgesamt korrekt war, aber im Falle von \u00dcbereinstimmungen zwischen 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\nElkina Ella;Kranf\u00fchrerin\nIvanova Alla;Maler\nIvanov Andrej;Installateur<\/code><\/pre>\n<p><\/p>\n<p>Sieht aus wie ein Sortierfehler in Unicode oder wie eine Manifestation von Feminismus im Sortieralgorithmus. Letzteres ist nat\u00fcrlich wahrscheinlicher.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Lassen wir es erstmal beiseite <em>beitreten<\/em> und konzentrieren uns auf <em>sortieren<\/em>. Versuchen wir, das Problem mit Trial and Error zu l\u00f6sen. Zuerst \u00e4ndern wir die Locale von <em>en_US<\/em> findet man <em>ru_RU<\/em>. F\u00fcr die Sortierung w\u00fcrde es ausreichen, die Umgebungsvariable <em>LC_COLLATE<\/em>, aber wir wollen es nicht so kleinlich machen:<\/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 eine einbyteartige Codierung umzuwandeln: <\/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>Da hilft nichts, wir m\u00fcssen im Internet nach einer L\u00f6sung suchen. Direkte Informationen \u00fcber russische Nachnamen gibt es nicht, aber es gibt Fragen zu anderen Sortierproblemen. Hier ist beispielsweise eine solche Problematik: <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 sortiert als &quot;aa&quot;, &quot;a-b&quot;, &quot;ac&quot;.<\/p>\n<p><\/p>\n<p>Die Antwort ist \u00fcberall gleich: Verwenden Sie die Programmier-Locale <em>&quot;C&quot;<\/em> und Sie werden gl\u00fccklich sein. Probieren wir es:<\/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 ver\u00e4ndert. Die Ivanovs sind nun in der richtigen Reihenfolge, aber Jolkina ist irgendwo hin gerutscht. 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 Jolkina in der ersten Zeile.<\/p>\n<p><\/p>\n<p>Das Problem scheint gel\u00f6st zu sein, aber vorsichtshalber probieren wir noch eine russische Kodierung aus \u2013 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 seltsamerweise mit der Locale \u00fcbereinstimmen. <em>&quot;C&quot;<\/em>, und das gesamte Beispiel verl\u00e4uft dementsprechend ohne Fehler. Irgendwelche Mystik.<\/p>\n<p><\/p>\n<p>Ich liebe keine Mystik in der Programmierung, da sie normalerweise Fehler verschleiert. Ich werde mich ernsthaft mit der Frage besch\u00e4ftigen, wie es funktioniert. <em>sortieren<\/em> und welchen Einfluss es 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 nicht richtig sortiert wurden.<\/li>\n<li>das <em>LANG=ru_RU.CP1251<\/em> stellte sich als \u00e4quivalent heraus. <em>LANG=C<\/em><\/li>\n<li>warum verschiedene <em>sortieren<\/em> und <em>beitreten<\/em> Darstellungen der sortierten Zeilen existieren.<\/li>\n<li>warum alle meine Beispiele Fehler enthalten.<\/li>\n<li>schlie\u00dflich, wie man die Zeilen nach seinem 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 collation algorithm<\/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 gestatte ich mir, eine kurze 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 selbst k\u00f6nnen variieren (&quot;Bubble Sort&quot;, &quot;Merge Sort&quot;, &quot;Quick Sort&quot;), aber alle nutzen den Vergleich von Paaren von Strings, um die Reihenfolge ihrer Anordnung zu bestimmen.<\/p>\n<p><\/p>\n<p>Die Sortierung von Strings in nat\u00fcrlicher Sprache ist ein recht komplexes Problem. Selbst in den einfachsten Ein-Byte-Codierungen stimmt die Reihenfolge der Buchstaben im Alphabet, wenn es sich von der englischen lateinischen Schrift unterscheidet, nicht mit den numerischen Werten \u00fcberein, die diese Buchstaben kodieren. So steht im deutschen Alphabet der Buchstabe <em>\u00d6<\/em> zwischen <em>e<\/em> und <em>P<\/em>, und in der Codierung <em>CP850<\/em> liegt er zwischen <em>\u00ff<\/em> und <em>\u00dc<\/em>.<\/p>\n<p><\/p>\n<p>Man kann versuchen, sich von der spezifischen Kodierung zu abstrahieren und &quot;ideale&quot; Buchstaben zu betrachten, die in einer bestimmten Reihenfolge angeordnet sind, wie es in Unicode der Fall ist. Kodierungen <em>UTF8<\/em>, <em>UTF16<\/em> oder die einbyteige <em>KOI8-R<\/em> (wenn ein begrenztes Teilmen\u00fc des Unicode ben\u00f6tigt wird) werden unterschiedliche numerische Darstellungen der Buchstaben liefern, sich aber gleichzeitig auf die gleichen Elemente der Basistabelle beziehen. <\/p>\n<p><\/p>\n<p>Es stellt sich heraus, dass wir selbst beim Erstellen einer Zeichentabelle von Grund auf keinen universellen Sortierungsauftrag f\u00fcr die Zeichen festlegen k\u00f6nnen. In verschiedenen nationalen Alphabeten, die dieselben Buchstaben verwenden, kann die Reihenfolge dieser Buchstaben unterschiedlich sein. Zum Beispiel im Franz\u00f6sischen <em>\u00c6<\/em> wird als Ligatur betrachtet und als Zeichenfolge sortiert. <em>Vereinigte Arabische Emirate<\/em>Im Norwegischen hingegen <em>\u00c6<\/em> ist es ein separater Buchstabe, der nach <em>Z<\/em>zu finden ist. \u00dcbrigens gibt es neben Ligaturen wie <em>\u00c6<\/em> auch Buchstaben, die mit mehreren Zeichen geschrieben werden. So gibt es im Tschechischen den Buchstaben <em>Ch<\/em>, der zwischen <em>H<\/em> und <em>I<\/em>.<\/p>\n<p><\/p>\n<p>liegt. Neben den Unterschieden in den Alphabeten gibt es auch andere nationale Traditionen, die die Sortierung beeinflussen. Insbesondere stellt sich die Frage: In welcher Reihenfolge sollten W\u00f6rter im W\u00f6rterbuch erscheinen, die aus Gro\u00df- und Kleinbuchstaben bestehen? Auch die Verwendung von Satzzeichen kann die Sortierung beeinflussen. Im Spanischen steht am Anfang eines Fragesatzes ein umgekehrtes Fragezeichen (<em>\u00bfTe gusta la m\u00fasica?<\/em>). In diesem Fall ist offensichtlich, dass Frage\u00e4tze nicht au\u00dferhalb des Alphabets in einen eigenen Cluster gruppiert werden sollten. Aber wie sortiert man Strings mit anderen Satzzeichen?<\/p>\n<p><\/p>\n<p>Ich werde nicht auf die Sortierung von Strings in stark von europ\u00e4ischen Sprachen abweichenden Sprachen eingehen. Ich m\u00f6chte darauf hinweisen, dass in Sprachen mit einer Schreibrichtung von rechts nach links oder von oben nach unten die Zeichen in Strings wahrscheinlich in der Reihenfolge des Lesens gespeichert sind, und selbst in nicht-alphabetischen Schriften gibt es Wege, Strings zeichenweise zu ordnen. Zum Beispiel k\u00f6nnen Hieroglyphen nach Form (<noindex><a rel=\"nofollow\" href=\"https:\/\/studychinese.ru\/kljuchi\/\">Schl\u00fcsseln chinesischer Hieroglyphen<\/a><\/noindex>) oder nach Aussprache sortiert werden. Wie Emojis sortiert werden sollten, kann ich ehrlich gesagt nicht sagen, aber auch daf\u00fcr kann man sich etwas einfallen lassen.<\/p>\n<p><\/p>\n<p>Auf der Grundlage der oben genannten Merkmale wurden die grundlegenden Anforderungen an den Vergleich von Strings, die auf Unicode-Tabellen basieren, formuliert:<\/p>\n<p><\/p>\n<ul>\n<li>der Vergleich von Strings h\u00e4ngt nicht von der Position der Zeichen in der Kodierungstabelle ab;<\/li>\n<li>Zeichenfolgen, die ein einzelnes Zeichen bilden, werden in die kanonische Form gebracht (<em>A<\/em> + der obere Punkt ist dasselbe wie <em>\u00c5<\/em>);<\/li>\n<li>Bei der Zeichenvergleich wird das Zeichen im Kontext der Zeichenfolge betrachtet und, falls erforderlich, mit benachbarten Zeichen zu einer Vergleichseinheit kombiniert (<em>Ch<\/em> im Tschechischen) oder in mehrere zerlegt (<em>\u00c6<\/em> im Franz\u00f6sischen);<\/li>\n<li>alle nationalen Besonderheiten (Alphabet, Gro\u00df-\/Kleinbuchstaben, Interpunktion, Reihenfolge der Schriftarten) m\u00fcssen bis hin zu manuellen Zuweisungen der Reihenfolge (Emojis) konfiguriert werden;<\/li>\n<li>der Vergleich ist nicht nur f\u00fcr die Sortierung wichtig, sondern auch an vielen anderen Stellen, beispielsweise f\u00fcr die Festlegung von Zeichenfolgenbereichen (Platzhalter {A\u2026 \u044f} in <em>bash<\/em>);<\/li>\n<li>der Vergleich sollte 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 Algorithmusentwickler nicht vertrauen sollten:<\/p>\n<p><\/p>\n<ul>\n<li>der Vergleichsalgorithmus sollte nicht f\u00fcr jede Sprache ein separates Zeichenset ben\u00f6tigen (Russisch und Ukrainisch verwenden gr\u00f6\u00dftenteils dieselben kyrillischen Zeichen);<\/li>\n<li>der Vergleich sollte nicht auf der Reihenfolge der Zeichen in den Unicode-Tabellen basieren;<\/li>\n<li>das Gewicht einer Zeichenfolge sollte kein Attribut der Zeichenfolge sein, da eine und dieselbe Zeichenfolge in unterschiedlichen kulturellen Kontexten unterschiedliche Gewichtungen haben kann;<\/li>\n<li>Die Gewichte der Zeichenfolgen k\u00f6nnen sich beim Zusammenf\u00fchren oder Aufteilen \u00e4ndern (aus <em>x<\/em> &lt; <em>y<\/em> es folgt nicht, dass <em>xz<\/em> &lt; <em>yz<\/em>);<\/li>\n<li>verschiedene Zeichenfolgen, die dieselben Gewichte aufweisen, als gleich angesehen werden im Sinne des Sortieralgorithmus. Eine zus\u00e4tzliche Anordnung solcher Zeichenfolgen ist m\u00f6glich, kann jedoch die Leistung beeintr\u00e4chtigen;<\/li>\n<li>bei wiederholten Sortierungen k\u00f6nnen Zeichenfolgen mit gleichen Gewichten ihre Pl\u00e4tze tauschen. Stabilit\u00e4t ist eine Eigenschaft eines bestimmten Sortieralgorithmus und nicht eine Eigenschaft des Vergleichsalgorithmus f\u00fcr Zeichenfolgen (siehe den vorherigen Punkt);<\/li>\n<li>Die Sortierregeln k\u00f6nnen sich im Laufe der Zeit \u00e4ndern, w\u00e4hrend kulturelle Traditionen verfeinert oder ge\u00e4ndert werden.<\/li>\n<\/ul>\n<p><\/p>\n<p>Es ist auch festgelegt, dass der Vergleichsalgorithmus nichts \u00fcber die Semantik der verarbeiteten Zeichenfolgen wei\u00df. So sollten Zeichenfolgen, die nur aus Ziffern bestehen, nicht als 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 allen angegebenen Anforderungen gerecht zu werden, wurde ein mehrstufiger (tats\u00e4chlich vierstufiger) tabellarischer Sortieralgorithmus vorgeschlagen.<\/p>\n<p><\/p>\n<p>Zun\u00e4chst werden die Zeichen in der Zeichenfolge in eine kanonische Form umgewandelt 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 in Bezug auf gr\u00f6\u00dfer-kleiner verglichen werden k\u00f6nnen. Ein spezieller Wert <em>IGNORED<\/em> (0x0) bedeutet, dass die betreffende Einheit auf der entsprechenden Vergleichsebene nicht am Vergleich teilnimmt. Der Vergleich von Zeichenfolgen kann mehrmals unter Verwendung der Gewichte der entsprechenden Ebenen wiederholt 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 k\u00f6nnen die Werte der Koeffizienten je nach nationaler Tradition variieren, aber der Unicode-Standard enth\u00e4lt eine grundlegende Gewichtungstabelle - <em>&quot;Default Unicode Collation Element Table&quot;<\/em> (<em>DUCET<\/em>). Ich m\u00f6chte darauf hinweisen, dass die Festlegung einer Variablen tats\u00e4chlich eine Anweisung zur Auswahl der Gewichtungstabelle in der Funktion zum Vergleich von Zeichenfolgen ist. <em>LC_COLLATE<\/em> Die Gewichtungskoeffizienten<\/p>\n<p><\/p>\n<p>sind wie folgt aufgebaut: <em>DUCET<\/em> sind wie folgt strukturiert:<\/p>\n<p><\/p>\n<ul>\n<li>Auf der ersten Ebene werden alle Buchstaben in eine einheitliche Schreibweise umgewandelt, diakritische Zeichen werden entfernt, und die Zeichensetzung (nicht alle) wird 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 die 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; anschlie\u00dfend eventuell der dritten und vierten.<\/p>\n<p><\/p>\n<p>Der Vergleich endet, wenn in den Zeichenfolgen \u00fcbereinstimmende Vergleichseinheiten mit unterschiedlichen Gewichten vorhanden sind. Zeichenfolgen, die in allen vier Ebenen die gleichen Gewichte aufweisen, gelten als gleichwertig.<\/p>\n<p><\/p>\n<p>Dieser Algorithmus (mit einer Menge zus\u00e4tzlichen technischen Details) gab den Namen f\u00fcr 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, dies mit dem Unicode-Standard zu vergleichen.<\/p>\n<p><\/p>\n<p>F\u00fcr Implementierungstests <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\">Gewichtedatei verwendet<\/a><\/noindex>, die <em>DUCET<\/em>. In der Datei mit den Gewichtungen kann man verschiedene Kuriosit\u00e4ten finden. Zum Beispiel gibt es dort die Reihenfolge der Mahjong-Steine und des europ\u00e4ischen Dominospiels sowie die Reihenfolge der Farben in einem Kartenspiel (Symbol <em>1F000<\/em> und weiter). Die Kartenfarben sind nach den Regeln des Bridge angeordnet \u2014 PCHBT, und die Karten innerhalb der Farben \u2014 in der Reihenfolge T, 2, 3\u2026 K.<\/p>\n<p><\/p>\n<p>Eine manuelle \u00dcberpr\u00fcfung der Richtigkeit der Sortierung der Zeilen gem\u00e4\u00df <em>DUCET<\/em> w\u00e4re ziemlich m\u00fchsam, aber zum Gl\u00fcck gibt es eine herausragende Implementierung der Bibliothek zur Arbeit mit 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>Auf der Webseite dieser Bibliothek, die in <em>IBM<\/em>, gibt es Demoseiten, darunter auch <noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">die Seite f\u00fcr den Vergleich von Zeichenfolgen<\/a><\/noindex>. Wir geben unsere Testzeichenfolgen mit den Standardeinstellungen ein und, oh Wunder, wir erhalten eine perfekte russische Sortierung.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Abakanov Michail;Maler\nYolkina Ella;Kranf\u00fchrerin\nIvanov Andrej;Schlosser\nIvanova Alla;Rechtsanw\u00e4ltin<\/code><\/pre>\n<p><\/p>\n<p>\u00dcbrigens finden Sie auf der Webseite <em>ICU<\/em> eine Erl\u00e4uterung zur Funktionsweise des Vergleichsalgorithmus bei der Verarbeitung von Satzzeichen. In den Beispielen <noindex><a rel=\"nofollow\" href=\"http:\/\/userguide.icu-project.org\/collation\/faq\">Collation FAQ<\/a><\/noindex> werden Apostrophe und Bindestrich ignoriert.<\/p>\n<p><\/p>\n<p>Unicode hat uns geholfen, aber die Gr\u00fcnde f\u00fcr das seltsame 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>Schnellansicht des Quellcodes des Dienstprogramms <em>sortieren<\/em> von <em>GNU Core Utils<\/em> zeigte, dass die Lokalisierung in dem Dienstprogramm auf den Druck des aktuellen Wertes der Variablen beschr\u00e4nkt ist <em>LC_COLLATE<\/em> bei der Ausf\u00fchrung im Debug-Modus:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ sort --debug buhg.txt &gt; buhg.srt\nsort: verwendet die Sortierregeln von \u2018en_US.UTF8\u2019<\/code><\/pre>\n<p><\/p>\n<p>Der Vergleich von Zeichenfolgen erfolgt mit der Standardfunktion <em>strcoll<\/em>, was bedeutet, dass alles Interessante in der Bibliothek zu finden ist <em>glibc.<\/em>.<\/p>\n<p><\/p>\n<p>Auf <em>Wiki<\/em> Projekts <em>glibc.<\/em> dem Vergleich von Zeichenfolgen gewidmet <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/glibc\/wiki\/Locales#LC_COLLATE\">ein Absatz<\/a><\/noindex>. Aus diesem Absatz kann man verstehen, dass die <em>glibc.<\/em> Sortierung auf dem bereits bekannten Algorithmus basiert <em>UCA<\/em> (<em>The Unicode collation algorithm<\/em>) und\/oder einem \u00e4hnlichen Standard <em>ISO 14651<\/em> (<em>Internationale Reihenfolge und Vergleich von Zeichenfolgen<\/em>). Zum letzten Standard sei angemerkt, 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, aber der entsprechende Link f\u00fchrt zu einer nicht existierenden Seite. Google bringt mehrere Seiten mit Links zu offiziellen Seiten hervor, die anbieten, eine elektronische Kopie des Standards f\u00fcr mehrere hundert Euro zu kaufen, aber auf der dritten oder vierten Seite der Suchergebnisse finden sich auch direkte Links zu <em>PDF<\/em>. Im Gro\u00dfen und Ganzen unterscheidet sich der Standard praktisch nicht von <em>UCA<\/em>, liest sich aber langweiliger, da er keine anschaulichen Beispiele nationaler Besonderheiten der Zeichenfolgensortierung enth\u00e4lt. <\/p>\n<p><\/p>\n<p>Die interessanteste Information war der <em>Wiki<\/em> Link zum <noindex><a rel=\"nofollow\" href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=14095\">Bugtracker<\/a><\/noindex> mit der Diskussion \u00fcber die Implementierung der Zeichenfolgenvergleiche in <em>glibc.<\/em>. Aus der Diskussion geht hervor, dass in <em>glibc.<\/em> zum Vergleich von Zeichenfolgen <em>ISO<\/em>eine Tabelle verwendet wird <noindex><a rel=\"nofollow\" href=\"http:\/\/www.iso.org\/ittf\/ISO14651_2006_TABLE1_en.txt\">Die Common Template Table<\/a><\/noindex> (<em>CTT<\/em>), deren Adresse im Anhang gefunden werden kann, <em>A<\/em> des Standards <em>ISO 14651<\/em>. Zwischen 2000 und 2015 hatte diese Tabelle keinen Maintainer und unterschied sich deutlich (zumindest optisch) von der aktuellen Version des Standards. Von 2015 bis 2018 wurde die Anpassung an die neue Version der Tabelle vorgenommen, und im Moment haben Sie die Chance, sowohl die neue Version der Tabelle ( <em>glibc.<\/em> ) als auch die alte (<em>CentOS 8<\/em>) im wirklichen Leben zu treffen. Nun, da wir alle Informationen \u00fcber den Algorithmus und die Hilfstabellen haben, k\u00f6nnen wir zur urspr\u00fcnglichen Problemstellung zur\u00fcckkehren und verstehen, wie man Zeichenfolgen in der russischen Lokalisierung richtig sortiert.<em>CentOS 7<\/em>). <\/p>\n<p><\/p>\n<p>ISO 14651\/14652<\/p>\n<p><\/p>\n<h1 id=\"iso-1465114652\">Der Quellcode der f\u00fcr uns interessanten Tabelle<\/h1>\n<p><\/p>\n<p>befindet sich in den meisten Distributionen <em>CTT<\/em> im Verzeichnis <em>Linux<\/em> . Die Tabelle selbst befindet sich in der Datei <em>\/usr\/share\/i18n\/locales\/<\/em>iso14651_t1_common <em>. Dann wird diese Datei \u00fcber die Direktive<\/em>copy iso14651_t1_common <em>in die Datei<\/em> iso14651_t1 <em>, die wiederum in die nationalen Dateien, einschlie\u00dflich in<\/em>, eingebunden ist. In den meisten Distributionen <em>en_US<\/em> und <em>ru_RU<\/em>. In den meisten Distributionen <em>Linux<\/em> Alle Quelldateien sind Teil der Basisinstallation, aber falls sie fehlen, muss ein zus\u00e4tzliches Paket aus der Distribution installiert werden.<\/p>\n<p><\/p>\n<p>Die Struktur der Datei <em>, die wiederum in die nationalen Dateien, einschlie\u00dflich in<\/em> Es kann 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 beschrieben <em>ISO 14652<\/em>, eine Kopie davon kann von der Website heruntergeladen werden <noindex><a rel=\"nofollow\" href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG20\/docs\/n972-14652ft.pdf\">open-std.org<\/a><\/noindex>. Eine weitere Beschreibung des Dateiformats kann in <noindex><a rel=\"nofollow\" href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/basedefs\/V1_chap07.html\">JSR 168 und JSR 286 sowie Frameworks wie<\/a><\/noindex> <em>POSIX<\/em> ab <em>OpenGroup<\/em>nachgelesen werden. Alternativ zur Lekt\u00fcre 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>betrachten. Die Struktur der Datei sieht folgenderma\u00dfen aus:<\/p>\n<p><\/p>\n<p>Standardm\u00e4\u00dfig wird das Zeichen  als Escape-Zeichen verwendet, und das Ende einer Zeile nach dem Zeichen # 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>Im Datei werden Tokens im Format <em>&lt;Uxxxx&gt;<\/em> oder <em>&lt;Uxxxxxxxx&gt;<\/em> (wo <em>x<\/em> \u2014 eine 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 ohne Kontext keine besondere Bedeutung haben.<\/p>\n<p><\/p>\n<p>Zeichenfolge <em>LC_COLLATE<\/em> sagt uns, dass die folgenden Daten die Zeichenvergleichsbeschreibung einleiten.<\/p>\n<p><\/p>\n<p>Zuerst werden die Gewichtsbezeichner in der Vergleichstabelle und die Namen f\u00fcr Zeichenkombinationen festgelegt. Grunds\u00e4tzlich geh\u00f6ren die zwei Arten von Namen zu zwei verschiedenen Entit\u00e4ten, aber in der tats\u00e4chlichen Datei sind sie vermischt. Die Gewichtsbezeichner werden durch das Schl\u00fcsselwort <em>collating-symbol<\/em> (Vergleichssymbol) angegeben, da Unicode-Zeichen mit denselben Gewichten beim Vergleichen als \u00e4quivalente Zeichen betrachtet werden.<\/p>\n<p><\/p>\n<p>Die Gesamtl\u00e4nge des Abschnitts in der aktuellen Datei betr\u00e4gt etwa 900 Zeilen. Ich habe Beispiele aus verschiedenen Stellen herausgesucht, um die Willk\u00fcr der Namen und einige Arten von Syntax zu zeigen.<\/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; % garantiert 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 Zeichenfolge <em>OSMANYA<\/em> in der Gewichtsnamen-Tabelle <\/li>\n<li><em>collating-symbol ..<\/em> registriert eine Reihenfolge von Namen, bestehend aus einem Pr\u00e4fix <em>O<\/em> und einem hexadezimalen numerischen Suffix von <em>1D000<\/em> bis zu <em>1D35F<\/em>.<\/li>\n<li><em>FFFF<\/em> in <em>collating-symbol<\/em> scheint wie eine gro\u00dfe nicht-negative Ganzzahl im hexadezimalen Zahlensystem auszusehen, aber <em>&lt;SFFFF&gt;<\/em> ist einfach ein Name, der so aussehen k\u00f6nnte wie <em>&lt;VERYBIGVAL&gt;<\/em> <\/li>\n<li>Name <em>&lt;U0413&gt;<\/em> bezeichnet einen Codepunkt in der Kodierung <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 Gewichte definiert sind, werden die Gewichte selbst festgelegt. Da bei Vergleichen nur die Relationen gr\u00f6\u00dfer-kleiner von Bedeutung sind, werden die Gewichte in einfacher Reihenfolge aufgez\u00e4hlt. Zuerst werden die &quot;leichteren&quot; Gewichte aufgez\u00e4hlt, gefolgt von den &quot;schwereren&quot;. Ich erinnere daran, dass jedem Unicode-Zeichen vier verschiedene Gewichte zugewiesen werden. Hier sind diese in einer einheitlichen geordneten Reihenfolge zusammengefasst. Theoretisch kann jeder symbolische Name auf jedem der vier Ebenen verwendet werden, aber Kommentare deuten darauf hin, dass Entwickler die Namen gedanklich nach Ebenen trennen.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">% Symbolische Gewichtzuweisungen\n\n% Gewichtzuweisungen dritter Ebene\n\n\n\n\n...\n% Gewichtzuweisungen zweiter Ebene\n\n % KOMBINIERE NIEDERLINE\n % KOMBINIERE KOMMA OBEN\n % KOMBINIERE UMGEKEHRTES KOMMA OBEN\n...\n% Gewichtzuweisungen erster Ebene\n % HORIZONTALE TABULIERUNG\n % ZEILENUMBRUCH\n % VERTIKALE TABULIERUNG\n...\n % KIRILLLISCHES KLEINBUCHSTABE DE\n % KIRILLLISCHES KLEINBUCHSTABE KOMI DE\n % KIRILLLISCHES KLEINBUCHSTABE DJE\n % KIRILLLISCHES KLEINBUCHSTABE KOMI DJE\n % KIRILLLISCHES KLEINBUCHSTABE GJE\n % KIRILLLISCHES KLEINBUCHSTABE ZE MIT ABSTEIGEN\n % KIRILLLISCHES KLEINBUCHSTABE IE\n % KIRILLLISCHES KLEINBUCHSTABE IE MIT BREVE\n % KIRILLLISCHES KLEINBUCHSTABE UKRAINISCHES IE\n % KIRILLLISCHES KLEINBUCHSTABE ZHE<\/code><\/pre>\n<p><\/p>\n<p>Schlie\u00dflich 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> bestimmen, in welcher Richtung die Zeilen auf jeder Vergleichsebene durchsucht werden. Standardm\u00e4\u00dfig wird der Parameter verwendet <em>forward<\/em>. Der Abschnitt besteht aus Zeilen, die den Zeichencode und vier seiner Gewichtungen enthalten. Der Zeichencode kann durch das Zeichen selbst, den Codepunkt oder einen vorher 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 (der Position in der Unicode-Tabelle). Nicht explizit angegebene Zeichen (so verstehe ich) werden als prim\u00e4r betrachtet, mit einem Gewicht, das der Position in der Unicode-Tabelle entspricht. Besondere Gewichtungswerte <em>IGNORE<\/em> bedeutet, dass dieses Zeichen auf der entsprechenden Vergleichsebene ignoriert wird.<\/p>\n<p><\/p>\n<p>Um die Struktur der Gewichtungen zu demonstrieren, habe ich drei ziemlich 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 dem Wert drei entsprechen<\/li>\n<li>der Beginn des kyrillischen Alphabets, das 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\">Bestellung_Start vor;vor;vor;vor,Position\n IGNORIEREN;IGNORIEREN;IGNORIEREN;IGNORIEREN % NULL (in 6429)\n IGNORIEREN;IGNORIEREN;IGNORIEREN;IGNORIEREN % ANFANG DES \u00dcBERSCHRIFTS (in 6429)\n IGNORIEREN;IGNORIEREN;IGNORIEREN;IGNORIEREN % TEXTBEGINN (in 6429)\n...\n ;;; % ZIFFER DREI\n ;;; % VOLLE ZIFFER DREI\n ;;; % IN KLAMMERN GESCHRIEBENE ZIFFER DREI\n ;;; % ZIFFER DREI VOLLSTRECKE\n ;;<FONT>; % MATHEMATISCH FETTE ZIFFER DREI\n...\n ;;; % CYRILLIC KLEINBUCHSTABE A\n ;;; % CYRILLIC GROSSBUCHSTABE A\n ;;; % CYRILLIC KLEINBUCHSTABE A MIT BREVE\n ;;; % CYRILLIC KLEINBUCHSTABE A MIT BREVE\n...\n ;;; % CYRILLIC KLEINBUCHSTABE BE\n ;;; % CYRILLIC GROSSBUCHSTABE BE\n ;;; % CYRILLIC KLEINBUCHSTABE VE\n ;;; % CYRILLIC GROSSBUCHSTABE VE\n...\nBestellung_Ende<\/code><\/pre>\n<p><\/p>\n<p>Jetzt k\u00f6nnen wir zu den Beispielen aus dem Anfang des Artikels zur\u00fcckkehren. Die Falle versteckt sich in diesem Teil der Gewichtungstabelle:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">IGNORIEREN;IGNORIEREN;IGNORIEREN; % LEERZEICHEN\n IGNORIEREN;IGNORIEREN;IGNORIEREN; % AUSRUFEZEICHEN\n IGNORIEREN;IGNORIEREN;IGNORIEREN; % ANF\u00dcHRUNGSZEICHEN\n...<\/code><\/pre>\n<p><\/p>\n<p>Es ist offensichtlich, dass in dieser Tabelle die Satzzeichen ignoriert werden. <em>ASCII<\/em> (einschlie\u00dflich Leerzeichen) werden beim Vergleich von Zeichenfolgen fast immer ignoriert. Die Ausnahme bilden nur Zeichenfolgen, die in allem \u00fcbereinstimmen, au\u00dfer bei den Satzzeichen, die an \u00fcbereinstimmenden Stellen vorkommen. Die Zeichenfolgen aus meinem Beispiel (nach der Sortierung) sehen f\u00fcr den Vergleichsalgorithmus so aus:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">AbakanovMichailMaler\nJolkinaEllaKranf\u00fchrerin\nIvanovaAllaMaler\nIvanovAndreiSchlosser<\/code><\/pre>\n<p><\/p>\n<p>Angesichts der Tatsache, dass in der Gewichtungstabelle die 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 Einstellung der Variablen <em>LC_COLLATE=C<\/em> wird eine spezielle Tabelle geladen, die einen byteweisen Vergleich definiert.<\/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\u00e4rtables<\/h1>\n<p><\/p>\n<p>Es ist offensichtlich, dass der Vergleich von Zeichenfolgen eine \u00e4u\u00dferst h\u00e4ufige Operation ist, w\u00e4hrend das Parsen einer Tabelle <em>CTT<\/em> eine ziemlich kostenintensive Prozedur darstellt. Um den Zugriff auf die Tabelle zu optimieren, wird sie in eine bin\u00e4re Form vom Befehl <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Der Befehl <em>localedef<\/em> kompiliert, der als Parameter eine Datei mit der Tabelle nationaler Besonderheiten (Option <em>-i<\/em>), in der alle Zeichen durch Unicode-Punkte dargestellt sind, und eine Datei zur Zuordnung von Unicode-Punkten zu den spezifischen Codierungen (Option <em>-f<\/em>). Dadurch werden bin\u00e4re Dateien 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 bedeutet, dass der Name der Locale der Name eines Unterverzeichnisses in <em>\/usr\/lib\/locale\/<\/em>. In diesem Unterverzeichnis werden die Bin\u00e4rdateien <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 geht davon aus, dass alle Locales in einem einzigen Archiv gespeichert werden <em>\/usr\/lib\/locale\/locale-archive<\/em>, das im virtuellen Speicher aller Prozesse angezeigt wird, die es verwenden. <em>glibc.<\/em>. Der Name der Locale im modernen Format unterliegt einer gewissen Kanonisierung \u2013 in den Kodierungsnamen bleiben nur Zahlen und Buchstaben, die in Kleinbuchstaben umgewandelt werden. So <em>ru_RU.KOI8-R<\/em>, wird als <em>ru_RU.koi8r<\/em>.<\/p>\n<p><\/p>\n<p>Eingabedateien 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 entsprechend gesucht.<\/p>\n<p><\/p>\n<p>Zum Beispiel wird 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>die Datei <em>\/usr\/share\/i18n\/locales\/ru_RU<\/em> unter Verwendung der Kodierungsdatei <em>\/usr\/share\/i18n\/charmaps\/MAC-CYRILLIC.gz<\/em> kompilieren und 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 wird, <em>glibc.<\/em> wird nach Bin\u00e4rdateien der Locale 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 vorkommt, erh\u00e4lt das moderne Format Priorit\u00e4t.<\/p>\n<p><\/p>\n<p>Die Liste der kompilierten Locales kann mit dem Befehl <em>locale -a<\/em>.<\/p>\n<p><\/p>\n<h1 id=\"podgotovka-svoey-tablicy-sravneniya\">vorbereitet werden.<\/h1>\n<p><\/p>\n<p>Nun, gewappnet mit Wissen, k\u00f6nnen Sie Ihre eigene ideale Vergleichstabelle von Zeichen erstellen. Diese Tabelle sollte russische Buchstaben korrekt vergleichen, einschlie\u00dflich des Buchstabens \u0401, und dabei die Satzzeichen gem\u00e4\u00df der Tabelle ber\u00fccksichtigen. <em>ASCII<\/em>.<\/p>\n<p><\/p>\n<p>Der Prozess zur Vorbereitung Ihrer Sortiertabelle besteht aus zwei Phasen: der Bearbeitung der Gewichtstabelle und der Kompilierung in bin\u00e4re Form mittels eines Befehls. <em>localedef<\/em>.<\/p>\n<p><\/p>\n<p>Um die Vergleichstabelle mit minimalem Bearbeitungsaufwand anzupassen, im Format <em>ISO 14652<\/em> sind Korrekturabschnitte f\u00fcr bereits bestehende Tabellen vorgesehen. Ein Abschnitt beginnt mit dem Schl\u00fcsselwort <em>reorder-after<\/em> und der Angabe der Position, nach der die Ersetzung erfolgt. Ein Abschnitt endet mit der Zeile <em>reorder-end<\/em>. Wenn es notwendig ist, mehrere Bereiche der Tabelle zu korrigieren, wird f\u00fcr jeden solchen Bereich ein eigener Abschnitt erstellt.<\/p>\n<p><\/p>\n<p>Ich habe die neuen Versionen der Dateien <em>. Dann wird diese Datei \u00fcber die Direktive<\/em> und <em>ru_RU<\/em> aus dem Repository <em>glibc.<\/em> in mein Home-Verzeichnis ~\/.local\/share\/i18n\/locales\/ kopiert und den Abschnitt <em>LC_COLLATE<\/em> in <em>ru_RU<\/em>leicht bearbeitet. 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 und den Beginn der Ersetzung in der Tabelle \u00e4ndern.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">LC_COLLATE\n% Kopiere die Vorlage von ISO\/IEC 14651\nkopiere &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; % RECHTER GERADE BRIKETT\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 ich die Felder \u00e4ndern m\u00fcssen <em>LC_IDENTIFICATION<\/em> so dass sie auf die Locale zeigen <em>ru_MY<\/em>, aber in meinem Beispiel war das nicht erforderlich, da ich das Archiv der Locales ausgeschlossen habe <em>locale-archive<\/em>.<\/p>\n<p><\/p>\n<p>Um <em>localedef<\/em> arbeitete mit den Dateien in meinem Ordner \u00fcber die Variable <em>I18NPATH<\/em> es ist m\u00f6glich, ein zus\u00e4tzliches Verzeichnis f\u00fcr die Suche nach Eingabedateien hinzuzuf\u00fcgen, und das Verzeichnis zum Speichern von Bin\u00e4rdateien kann als Pfad mit Schr\u00e4gstrichen angegeben werden:<\/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> es wird davon ausgegangen, dass in <em>LANG<\/em> absolute Pfade zu den Verzeichnissen mit den Locale-Dateien angegeben werden k\u00f6nnen, die mit einem normalen Schr\u00e4gstrich beginnen, 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 Einstellung <em>LOCPATH=~\/.local\/lib\/locale\/<\/em> werden alle mit der Lokalisierung verbundenen Dateien nur in meinem Ordner gesucht. Das Archiv der Locales wird bei gesetzter Variablen <em>LOCPATH<\/em> wird ignoriert.<\/p>\n<p><\/p>\n<p>Hier ist der entscheidende Test:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LANG=de_DE.UTF-8 LOCPATH=~\/.local\/lib\/locale\/ sort buhg.txt\nAbakanow Michail;Maler\nJolkina Ella;Kranf\u00fchrerin\nIvanow Andrej;Schlosser\nIvanova 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 von Strings beantwortet, die zu Beginn gestellt wurden, aber es sind noch ein paar Fragen zu den Fehlern \u00fcbrig geblieben \u2013 sowohl sichtbare als auch unsichtbare.<\/p>\n<p><\/p>\n<p>Zur\u00fcck zur urspr\u00fcnglichen Aufgabe.<\/p>\n<p><\/p>\n<p>Und das Programm <em>sortieren<\/em> und das Programm <em>beitreten<\/em> verwenden dieselben Stringvergleichsfunktionen aus <em>glibc.<\/em>. Wie konnte es also dazu kommen, dass <em>beitreten<\/em> einen Sortierfehler bei den von der Kommandozeile sortierten Strings ausgegeben hat? <em>sortieren<\/em> in der Locale <em>de_DE.UTF-8<\/em>? \u041e\u0442\u0432\u0435\u0442 \u043f\u0440\u043e\u0441\u0442: <em>sortieren<\/em> vergleicht die gesamte Zeichenkette, w\u00e4hrend <em>beitreten<\/em> nur den Schl\u00fcssel vergleicht, der standardm\u00e4\u00dfig der Anfang der Zeichenkette bis zum ersten Leerzeichen ist. In meinem Beispiel f\u00fchrte dies zu einer Fehlermeldung, da die Sortierung der ersten W\u00f6rter in den Strings nicht mit der Sortierung der gesamten Strings \u00fcbereinstimmte.<\/p>\n<p><\/p>\n<p>Locale <em>&quot;C&quot;<\/em> garantiert, dass die sortierten Zeilen auch die Anfangsunterstrings bis zum ersten Leerzeichen sortiert haben, aber das ist nur ein Maskierungstrick f\u00fcr einen Fehler. Man kann solche Daten ausw\u00e4hlen (Menschen mit denselben Nachnamen, aber unterschiedlichen Vornamen), die ohne Fehlermeldung zu einem falschen Ergebnis bei der Zusammenf\u00fchrung von Dateien f\u00fchren w\u00fcrden. Wenn wir m\u00f6chten, dass <em>beitreten<\/em> die Zeilen von Dateien nach Vollst\u00e4ndigen Namen (FIO) zusammengef\u00fchrt werden, ist die richtige Vorgehensweise die explizite Angabe des Feldtrennzeichens und die Sortierung nach dem Schl\u00fcssel, nicht nach der gesamten Zeile. In diesem Fall wird auch die Zusammenf\u00fchrung korrekt durchgef\u00fchrt, 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 durchgef\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> in den Paketen die kompilierte Locale <em>ru_RU.CP1251<\/em>fehlt. Wenn die kompilierte Locale nicht gefunden wird, <em>sortieren<\/em> verwendet sie stillschweigend den byteweisen Vergleich, was wir auch beobachtet haben.<\/p>\n<p><\/p>\n<p>\u00dcbrigens gibt es noch einen kleinen Fehler im Zusammenhang mit der Nichtverf\u00fcgbarkeit 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> f\u00fcr alle Programme (auch f\u00fcr das selbst <em>locale<\/em>) werden diese Locales nicht verf\u00fcgbar sein.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; LOCPATH=\/tmp locale -a | grep en_US\nlocale: Kann LC_CTYPE nicht auf die Standard-Locale setzen: Datei oder Verzeichnis nicht gefunden\nlocale: Kann LC_MESSAGES nicht auf die Standard-Locale setzen: Datei oder Verzeichnis nicht gefunden\nlocale: Kann LC_COLLATE nicht auf die Standard-Locale setzen: 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 einfachen Bytevergleich<\/code><\/pre>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Fazit<\/h1>\n<p><\/p>\n<p>Wenn Sie ein Programmierer sind, der gewohnt ist, 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\u00f6rterbuchverfasser sind, sollten Sie Ihre Locale besser selbst kompilieren.<\/p>\n<p><\/p>\n<p>Wenn Sie ein einfacher Benutzer sind, sollten Sie sich damit abfinden, dass der Befehl <em>ls -a<\/em> Dateien ausgibt, die mit einem Punkt beginnen, zusammen mit Dateien, die mit einem Buchstaben beginnen, und <em>Midnight Commander<\/em>, der seine eigenen internen Funktionen zur Sortierung von Namen verwendet, die Dateien, die mit einem Punkt beginnen, an den Anfang der Liste stellt.<\/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-Kollationsalgorithmus <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/www.unicode.org\/Public\/UCA\/latest\/allkeys.txt\">Gewichte von 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> - Implementierung der Unicode-Bibliothek von IBM. <\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/demo.icu-project.org\/icu-bin\/collation.html\">Sortierungstest 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\">Zeichen gewichten 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 Gewichtungen <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 4.9.10 - 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 \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\" \/>\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) 4.9.10\" \/>\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 \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\" \/>\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 sortiert der Linux-Befehl sort Zeichenfolgen | ProHoster","description":"Einf\u00fchrung Alles begann mit einem kurzen Skript, das die Informationen \u00fcber die E-Mail-Adressen der Mitarbeiter, die aus der Liste der Mailinglistenbenutzer stammen, mit den Positionen der Mitarbeiter, die aus der Personalabteilung stammen, zusammenf\u00fchren sollte. Beide Listen wurden in Textdateien im Unicode UTF-8-Format exportiert und mit Unix-Zeilenenden gespeichert. Inhalt von mail.txt \u0418\u0432\u0430\u043d\u043e\u0432 \u0410\u043d\u0434\u0440\u0435\u0439;ia@example.com Inhalt von buhg.txt \u0418\u0432\u0430\u043d\u043e\u0432\u0430 \u0410\u043b\u043b\u0430;\u043c\u0430\u043b\u044f\u0440 \u0401\u043b\u043a\u0438\u043d\u0430","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 \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","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"},"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}]}}