Yerel ayarınızın karakter kodlaması (söyleyebileceğiniz locale charmap
) karakter başına çok baytlıktır.
Günümüzde en yaygın olanı, karakterlerin 1 ile 4 bayt arasında kodlanabileceği UTF-8'dir. Tüm bayt dizileri UTF-8'de geçerli karakterler oluşturmaz. UTF-8'deki her ASCII olmayan karakter, en yüksek iki bit kümesine sahip bir baytla başlar ve en yüksek (ancak en yüksek ikinci bit olmayan) bit kümesinin kaç baytı izlediğini söyler.
/dev/urandom
rastgele bir bayt akışı içerir. tr
karakteri çevirir, bu yüzden bu baytları karakter olarak çözmesi gerekir. Aralığınızdaki ASCII karakterlerinin tümü UTF-8'deki bir karakterde kodlanmıştır, ancak tr
yine de tüm karakterlerin kodunu çözmesi gerekir. Örneğin A
, 0x41 bayt (kod için A
) dışında bazı karakterlerin bulunduğu diğer çok baytlı kodlamalar da vardır .
Çünkü bu rastgele bayt akışı geçersiz diziler içerecek şekilde bağlanır (örneğin ASCII olmayan bir karakterin 0xc1'den büyük bir bayt ile başlaması gerektiğinden, UTF-8'de kendi başına bir 0x80 bayt geçersizdir (0xc0 ve 0xc1 UTF 8 karakter)), öyleyse tr
bu olduğunda bir hata ile döner.
Burada istediğiniz şey, bayt akışını, karakter başına bir bayt olan bir kodlamada karakter olarak düşünmektir. Hangisini seçerseniz seçin sizin aralığında bu karakterlerin tümü kadar önemli değildir (gibi AZ tarafından varsaysak, demek ABCDEFGHIJKLMNOPQRSTUVWXYZ şeylerden değil Ý
, Ê
) bu yüzden sisteminizde desteklenen tüm chartsets'ten aynı kodlanmış taşınabilir karakter kümesine dahil bulunmaktadır.
Bunun için, belirlersiniz LC_CTYPE
kullanılan ve hangi gibi şeyler hangi charset karar biridir yerelleştirme değişkeni blank
, alpha
karakter sınıfları içerir. Ancak, AZ aralığının tanımı için, LC_COLLATE
değişkeni de (dize sıralamasına karar veren) ayarlamak isteyeceksiniz .
C
Aka POSIX
yerel bir garanti karakterleri olduğundan tek bayt ve AZ ABCDEFGHIJKLMNOPQRSTUVWXYZ olduğunu. Yapabilirsin:
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(burada -
sonuna kadar hareket etmek , aksi halde, )-+
bir menzil gibi olacaktı A-Z
)
Ama dikkat bu LC_ALL
değişken diğer tüm geçersiz kılar LC_*
ve LANG
değişkenleri. Bu nedenle, eğer LC_ALL
önceden tanımlanmışsa, yukarıdakilerin hiçbir etkisi olmaz. Yani bunun yerine basitçe yapabilirsiniz:
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
Bu, hata mesajlarının dili gibi diğer şeyleri etkileyecektir, ancak yine de, LC_CTYPE'yi değiştirmek zaten hata mesajları için bir sorun olabilir (örneğin, C yerel ayarında Rusça veya Japonca hata mesajlarını ifade etmenin bir yolu yoktur).
xargs
...