Warum macht sed nicht das, was in der Gebietsschema-Sortierdatei für grep (und sed, awk) definiert ist?

Warum macht sed nicht das, was in der Gebietsschema-Sortierdatei für grep (und sed, awk) definiert ist?

Eine Datei mit allen (druckbaren) ASCII-Zeichen haben:

$ printf '%b' "$(printf '\\U%x\n' {32..126})" > file

Dies könnte sortiert werden (mithilfe von tr, um die lange Ausgabe auf eine Zeile zu reduzieren):

$ sort file | tr -d '\n'
 !"#%&'()*+,-./:;<=>?@[\]^_`{|}~$0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ

Zeigt, dass auf einem Debian-Buster-Computer mit einem en_US.utf8-Gebietsschema die Sortierung (für einzelne Zeichen) zuerst alle Satzzeichen, dann Zahlen und dann gemischte Groß- und Kleinbuchstaben enthält. Das heißt: aAbB, Klein- und Großbuchstaben zusammen.

Nehmen wir an, dass dies richtig ist und dass dies das ist, was der Benutzer (also ich) mit der Sortierung erreichen möchte.

Auf demselben System geschieht jedoch ohne weitere Änderungen Folgendes:

$ grep '[a-z]' file | tr -d '\n'
abcdefghijklmnopqrstuvwxyz

Das heißt, der Bereich a-zwird durch etwas in ausschließlich kleine ASCII-Buchstaben übersetzt.

Wer macht die Übersetzung und wie kann dies kontrolliert oder geändert werden?

Ich frage nicht, was Kleinbuchstaben sind oder was ein [az] bedeuten soll oder was jemand damit sagen möchte.

Ich gehe davon aus, dass dies [a-z]ein Bereich ist, der am beginnt aund am endetz in der Sortierreihenfolge.

Ich verstehe, dass manche andere Benutzer möchten, dass dies [a-z]in allen Gebietsschemas dasselbe bedeutet wie „Kleinbuchstaben“. Und ich könnte standardmäßig „damit leben“.

Aber wie kann ich das bei Bedarf steuern und/oder ändern? Wo ist der Knopf zum Ändern?

Nein, das Ändern der Sortierdateien hilft nicht. Etwas anderes geht darüber hinaus und verstärkt die persönliche Ansicht, dass „a“ [a-z]in allen Gebietsschemas immer ASCII-Kleinbuchstaben bedeuten muss.

Antwort1

Ich habe gelesen, wasPOSIX-Zustände. Meiner Interpretation nach gibt es zwei nicht-äquivalente Konzepte:

  • Sortierreihenfolge (Sortierungsreihenfolge)
  • Sortierreihenfolge

Relevante Fragmente [Hervorhebung von mir]:

Die LC_COLLATEKategorie bietet eineSortierreihenfolgeDefinition für zahlreiche Dienstprogramme im Band „Shell and Utilities“ von POSIX.1-2017 ( ls, sort, usw.), reguläre Ausdrucksübereinstimmung (siehe Reguläre Ausdrücke) und die Funktionen strcoll(), strxfrm(), wcscoll(), und wcsxfrm()im Band „System Interfaces“ von POSIX.1-2017.

ASortierreihenfolgeDie Definition soll die relative Reihenfolge zwischen Sortierelementen (Zeichen und Sortierelemente mit mehreren Zeichen) im Gebietsschema definieren. Diese Reihenfolge wird in Form von Sortierwerten ausgedrückt, d. h. indem jedem Element ein oder mehrere Sortierwerte (auch als Sortiergewichte bezeichnet) zugewiesen werden. […]

Das order_startSchlüsselwort muss vorangestellt werdenSortierreihenfolgeEinträge und definieren Sie auch die Anzahl der Gewichte für dieseSortierreihenfolgeDefinition und andere Sortierregeln.

DerSortierreihenfolgewie in diesem Abschnitt definiert, beeinflusst die Interpretation von Klammerausdrücken in regulären Ausdrücken (siehe RE Klammerausdruck).

Denn sortes kommt auf die Sortierreihenfolge an, also auf die Gewichte. Denn es kommt auf grep '[a-z]'die Sortierreihenfolge an, also auf die Reihenfolge der Sortierreihenfolgeneinträge.

Leider ist nur die Sortierreihenfolgeexplizit definiert, es gibt also keinen klaren Hinweis darauf, dass es sich bei der Sortierreihenfolge um ein anderes Konzept handelt.

Sortierreihenfolge
Die relative Reihenfolge der Sortierelemente, wie sie durch die Einstellung der LC_COLLATEKategorie im aktuellen Gebietsschema bestimmt wird. Die Sortierreihenfolge wird zum Sortieren verwendet und wird aus den jedem Sortierelement zugewiesenen Sortiergewichtungen bestimmt. Wenn keine Gewichtungen vorhanden sind, ist die Sortierreihenfolge die Reihenfolge, in der die Sortierelemente zwischen order_startund order_endSchlüsselwörtern in der LC_COLLATEKategorie angegeben werden.


In meinem Debian 9 verweisen viele Locales, wenn es um geht LC_COLLATE, letztendlich auf iso14651_t1_common(also /usr/share/i18n/locales/iso14651_t1_common). Der relevante Ausschnitt der Datei sieht folgendermaßen aus:

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U00AA> <a>;<PCL>;<EMI>;IGNORE # 199 ª
<U00E1> <a>;<ACA>;<MIN>;IGNORE # 200 á
[…]
<U0062> <b>;<BAS>;<MIN>;IGNORE # 233 b
<U0253> <b>;<CRL>;<MIN>;IGNORE # 234 ɓ
<U1E03> <b>;<PCT>;<MIN>;IGNORE # 235 ḃ
[…]
<U007A> <z>;<BAS>;<MIN>;IGNORE # 507 z
<U017A> <z>;<ACA>;<MIN>;IGNORE # 508 <z'>
<U017E> <z>;<CAR>;<MIN>;IGNORE # 509 <z<>
[…]
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
<U00C1> <a>;<ACA>;<CAP>;IGNORE # 518 Á
<U00C0> <a>;<GRA>;<CAP>;IGNORE # 519 À
[…]
<U0042> <b>;<BAS>;<CAP>;IGNORE # 550 B
<U1E02> <b>;<PCT>;<CAP>;IGNORE # 551 <B.>
<U1E04> <b>;<BPT>;<CAP>;IGNORE # 552 Ḅ
[…]
<U005A> <z>;<BAS>;<CAP>;IGNORE # 813 Z
<U0179> <z>;<ACA>;<CAP>;IGNORE # 814 <Z'>
<U017D> <z>;<CAR>;<CAP>;IGNORE # 815 <Z<>

Dies ist dasSortierreihenfolge. [a-z]enthält nicht A, da der Eintrag für A( <U0041>) nicht zwischen den Einträgen für aund steht z.

Die Einträge für aund Ageben immer noch dasselbe Sortiersymbol an <a>. Ebenso geben bund Ban <b>. Dies entspricht den Gewichten:

Gewichte werden als Zeichen (in einer der in der Gebietsschemadefinition angegebenen Formen), <collating-symbol>s, <collating-element>s, Auslassungspunkte oder das Sonderzeichen ausgedrückt IGNORE. Ein einzelnes Zeichen, ein <collating-symbol>oder ein <collating-element>soll die relative Position im Zeichen darstellen.Sortierreihenfolgedes Zeichens oder Symbols, und nicht des Zeichens oder der Zeichen selbst. Anstatt den Gewichten absolute Werte zuzuweisen, wird ein bestimmtes Gewicht also durch den relativen Ordnungswert ausgedrückt, der einem Sortierelement basierend auf seiner Reihenfolge im Zeichen zugewiesen wird.Sortierreihenfolge.

In der Datei sind <a>und <b>in dieser Reihenfolge definiert:

collating-symbol <a>
collating-symbol <b>

Dies macht die relevante Teilfolge vonSortierreihenfolgesein aAbB. Das ist es, was für zählt sort.


Um dies zu bestätigen, habe ich (vorübergehend) den folgenden Sortierreihenfolgeeintrag verschoben

<U004B> <k>;<BAS>;<CAP>;IGNORE # 649 K

an eine Position direkt vor dem Eintrag für v, also irgendwo zwischen aund z. Ich habe meine Gebietsschemata mit neu erstellt locale-gen. Gibt jetzt sort file | tr -d '\n'immer noch zurück …iIjJkKlLmM…(die Gewichte haben sich nicht geändert, die Sortierreihenfolge hat sich nicht geändert), grep '[a-z]' file | tr -d '\n'ergibt aber:

Kabcdefghijklmnopqrstuvwxyz

Das heißt, ich habe durch Ändern der Sortierreihenfolge Kdie Zugehörigkeit hergestellt.[a-z]

Wenn Sie eine Permutation von statt grep '[a-z]' file | tr -d '\n'zurückgeben möchten , müssen Sie ein Gebietsschema mit anderer Sortierreihenfolge verwenden. Es kann ein benutzerdefiniertes Gebietsschema sein.aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZabcdefghijklmnopqrstuvwxyz

verwandte Informationen