ロケールの文字エンコード(でわかる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...の興味深い使用