Die Zeichencodierung Ihres Gebietsschemas (die Sie erkennen können locale charmap) besteht aus einem Multi-Byte pro Zeichen.
Heutzutage ist UTF-8 am gebräuchlichsten, bei dem Zeichen über 1 bis 4 Bytes codiert werden können. Nicht alle Bytefolgen bilden in UTF-8 gültige Zeichen. Jedes Nicht-ASCII-Zeichen in UTF-8 beginnt mit einem Byte, in dem die zwei höchsten Bits gesetzt sind, und gibt an, wie viele Bytes mit dem höchsten (aber nicht dem zweithöchsten) gesetzten Bit folgen.
/dev/urandomenthält einen zufälligen Strom von Bytes. trtranskribiert Zeichen, daher müssen diese Bytes als Zeichen dekodiert werden. Diese ASCII-Zeichen in Ihrem Bereich sind alle in UTF-8 für ein Zeichen codiert, müssen jedoch trnoch alle Zeichen decodieren. Es gibt zum Beispiel andere AMehrbyte -Codierungen, bei denen einige andere Zeichen als das 0x41-Byte (der Code für A) enthalten.
Da dieser zufällige Bytestrom zwangsläufig ungültige Sequenzen enthält (zum Beispiel ist ein 0x80-Byte für sich in UTF-8 ungültig, da ein Nicht-ASCII-Zeichen mit einem Byte beginnen muss, das größer als 0xc1 ist (0xc0 und 0xc1 befinden sich in keinem UTF- 8 Zeichen)), wird also in diesem trFall mit einem Fehler zurückgegeben.
Was Sie hier wünschen, ist, diesen Strom von Bytes als Zeichen in einer Kodierung zu betrachten, die ein Byte pro Zeichen hat. Unabhängig davon , welche Sie wählen , ist nicht wichtig , da alle diese Zeichen in Ihrem Bereich (unter der Annahme von AZ, Sie bedeutete ABCDEFGHIJKLMNOPQRSTUVWXYZ und nicht Dinge wie Ý, Ê) sind Teil des tragbaren Zeichensatz so das gleiche in allen charsets auf Ihrem System unterstützt codiert werden.
Dafür würden Sie die eingestellte LC_CTYPELokalisierung Variable , die derjenige ist, der die charset entscheidet verwendet wird und welche Dinge wie blank, alphaZeichenklassen enthalten. Für die Definition des AZ-Bereichs möchten Sie jedoch auch die LC_COLLATEVariable festlegen (diejenige, die über die Reihenfolge der Zeichenfolgen entscheidet).
Das Gebietsschema Caka POSIXgarantiert, dass Zeichen Einzelbytes sind, und AZ ist ABCDEFGHIJKLMNOPQRSTUVWXYZ. Du könntest es tun:
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(hier das -ans ende verschieben, sonst )-+wäre das als bereich zu nehmen wie A-Z)
Beachten Sie jedoch, dass die LC_ALLVariable alle anderen LC_*und LANGVariablen überschreibt . Wenn LC_ALLalso bereits etwas anderes definiert ist, hat das oben Gesagte keine Auswirkung. Also können Sie stattdessen einfach Folgendes tun:
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
Dies wirkt sich auf andere Dinge wie die Sprache der Fehlermeldungen aus. Das Ändern von LC_CTYPE könnte jedoch bereits ein Problem für Fehlermeldungen gewesen sein (z. B. keine Möglichkeit, russische oder japanische Fehlermeldungen im Zeichensatz des Gebietsschemas C auszudrücken).
xargs...