ロケールの文字エンコード(でわかるlocale charmap
)は、文字ごとにマルチバイトです。
最も一般的なのは、文字を1〜4バイトでエンコードできるUTF-8です。すべてのバイトシーケンスがUTF-8で有効な文字を形成するわけではありません。UTF-8のすべての非ASCII文字は、2つの最上位ビットが設定された1バイトで始まり、最上位(2番目に上位ではない)ビットセットが続くバイト数を示します。
/dev/urandom
バイトのランダムストリームが含まれます。tr
文字を音訳するため、これらのバイトを文字としてデコードする必要があります。範囲内のASCII文字はすべてUTF-8で1文字にエンコードされますが、tr
それでもすべての文字をデコードする必要があります。たとえばA
、0x41バイト(のコードA
)以外の文字が含まれる他のマルチバイトエンコーディングがあります。
バイトのランダムストリームは無効なシーケンスを含むようにバインドされているため(たとえば、非ASCII文字は0xc1より大きいバイトで始まる必要があるため、0x80バイト自体はUTF-8では無効です(0xc0および0xc1はUTF- 8文字))、それtr
が発生するとエラーを返します。
ここで必要なのは、バイトストリームが文字ごとに1バイトのエンコーディングの文字として考えられることです。どちらを選択すること(AZによって仮定して、あなたはABCDEFGHIJKLMNOPQRSTUVWXYZを意味していないようなものは、あなたの範囲内のすべてのものを文字として重要ではありませんÝ
、Ê
)ので、あなたのシステムでサポートされているすべての文字セットで同じことをエンコードするポータブル文字セットの一部です。
そのために、LC_CTYPE
ローカライズ変数を設定します。これは、使用される文字セットとblank
、alpha
文字クラスに含まれるものなどを決定する変数です。ただし、AZの範囲を定義するには、LC_COLLATE
変数(文字列の順序を決定する変数)も設定する必要があります。
C
別名POSIX
ロケールは1保証の文字があることを、シングルバイトで、AZはABCDEFGHIJKLMNOPQRSTUVWXYZです。できること:
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(ここで-
最後に移動すると、そうでなければ、の)-+
ような範囲として取られますA-Z
)
しかし、そのノートLC_ALL
の変数は、他のすべての上書きされますLC_*
とLANG
、変数を。したがって、LC_ALL
が既に定義されている場合、上記の効果はありません。そのため、代わりに次のことができます。
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
それはエラーメッセージの言語のような他のものに影響を及ぼしますが、とにかく、LC_CTYPEの変更はすでにエラーメッセージの問題であるかもしれません(たとえば、Cロケールの文字セットでロシア語または日本語のエラーメッセージを表現する方法はありません)。
xargs
...の興味深い使用