การเข้ารหัสอักขระของโลแคลของคุณ (ซึ่งคุณสามารถบอกได้locale charmap
) เป็นหลายไบต์ต่ออักขระหนึ่งตัว
ปัจจุบันที่พบบ่อยที่สุดคือ UTF-8 ซึ่งสามารถเข้ารหัสอักขระได้ตั้งแต่ 1 ถึง 4 ไบต์ ลำดับของไบต์ทั้งหมดไม่ใช่อักขระที่ถูกต้องใน UTF-8 อักขระที่ไม่ใช่ ASCII ทุกตัวใน UTF-8 เริ่มต้นด้วยหนึ่งไบต์ที่มีบิตสูงสุดสองชุดและบอกจำนวนไบต์ที่มีบิตสูงสุด (แต่ไม่สูงสุดสอง) ตามมา
/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
aka POSIX
สถานที่เกิดเหตุเป็นหนึ่งในตัวละครที่มีการค้ำประกันเดียวไบต์และอาริโซน่าเป็น 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
...