आपके लोकेल का कैरेक्टर एन्कोडिंग (जिसे आप बता सकते हैं locale charmap
) एक मल्टी-बाइट प्रति कैरेक्टर एक है।
आजकल सबसे आम यूटीएफ -8 है जहां पात्रों को 1 से 4 बाइट्स पर एन्कोड किया जा सकता है। यूटीएफ -8 में बाइट्स के सभी अनुक्रम वैध वर्ण नहीं बनाते हैं। UTF-8 में प्रत्येक गैर-ASCII चरित्र एक बाइट के साथ शुरू होता है जिसमें दो उच्चतम बिट्स सेट होते हैं और बताते हैं कि कितने बाइट उच्चतम (लेकिन दूसरे-उच्चतम) बिट सेट का अनुसरण नहीं करते हैं।
/dev/urandom
बाइट्स की एक यादृच्छिक धारा शामिल है। tr
चरित्र का अनुवाद करता है, इसलिए इसे उन बाइट्स को पात्रों के रूप में डिकोड करना होगा। आपकी श्रेणी के वे ASCII वर्ण सभी UTF-8 में एक वर्ण पर एन्कोडेड हैं, लेकिन फिर tr
भी सभी वर्णों को डीकोड करने की आवश्यकता है। उदाहरण के लिए अन्य मल्टी-बाइट एन्कोडिंग हैं, जहां A
0x41 बाइट (कोड के लिए A
) के अलावा कुछ वर्ण हैं ।
चूँकि बाइट्स की रैंडम स्ट्रीम में अमान्य अनुक्रम होते हैं (उदाहरण के लिए 0x80 बाइट अपने आप में UTF-8 में अमान्य है क्योंकि गैर-ASCII वर्ण को बाइट के साथ शुरू करना पड़ता है कि 0xc1 (0xc0 और 0xc1) कोई UTF- में नहीं हैं 8 वर्ण)), ऐसा tr
होने पर एक त्रुटि के साथ लौटता है।
यहां आप जो चाहते हैं, उस बाइट की धारा को एन्कोडिंग के पात्रों के रूप में माना जाता है, जिसमें प्रति वर्ण एक बाइट होता है। जो भी आप चुनते हैं, वह आपकी सीमा के सभी वर्णों के रूप में महत्वपूर्ण नहीं है (AZ द्वारा मान लिया गया है, आपका मतलब ABCDEFGHIJKLMNOPQRSTUVWXYZ है और जैसी चीजें नहीं हैं ) Ý
, Ê
पोर्टेबल वर्ण सेट का हिस्सा हैं , इसलिए आपके सिस्टम पर समर्थित सभी वर्णमालाओं में समान है।
उसके लिए, आप LC_CTYPE
स्थानीयकरण चर सेट करेंगे जो वह है जो यह तय करता है कि किस वर्ण का उपयोग किया गया है और कौन सी चीजें पसंद हैं blank
, alpha
चरित्र वर्ग शामिल हैं। लेकिन AZ रेंज की परिभाषा के लिए, आप LC_COLLATE
चर (स्ट्रिंग ऑर्डर करने का निर्णय लेने वाला) को भी सेट करना चाहेंगे ।
C
उर्फ POSIX
स्थान एक एकल बाइट्स कि गारंटी देता है चरित्र है और 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 को बदलना पहले से ही त्रुटि संदेशों (उदाहरण के लिए, सी लोकेल की वर्णमाला में रूसी या जापानी त्रुटि संदेशों को व्यक्त करने का कोई तरीका नहीं) के लिए एक समस्या हो सकती थी।
xargs
...