La codifica dei caratteri della tua locale (che puoi capire locale charmap) è un multibyte per carattere.
Il più comune al giorno d'oggi è UTF-8 in cui i caratteri possono essere codificati da 1 a 4 byte. Non tutte le sequenze di byte formano caratteri validi in UTF-8. Ogni carattere non ASCII in UTF-8 inizia con un byte con i due bit più alti impostati e indica quanti byte seguono il set di bit più alto (ma non il secondo più alto).
/dev/urandomcontiene un flusso casuale di byte. trtraslittera carattere, quindi deve decodificare quei byte come caratteri. Quei caratteri ASCII nel tuo intervallo sono tutti codificati su un carattere in UTF-8, ma trdevono comunque decodificare tutti i caratteri. Esistono ad esempio altre codifiche multi-byte in cui alcuni caratteri diversi da quelli Acontengono il byte 0x41 (il codice per A).
Perché quel flusso casuale di byte è destinato a contenere sequenze non valide (ad esempio un byte 0x80 da solo non è valido in UTF-8 poiché un carattere non ASCII deve iniziare con un byte maggiore di 0xc1 (0xc0 e 0xc1 non sono in UTF- 8 caratteri)), quindi trritorna con un errore quando ciò accade.
Quello che vuoi qui è considerare quel flusso di byte come caratteri in una codifica che ha un byte per carattere. Quale scegliete non è importante come tutti quei personaggi nella vostra gamma (assumendo AZ, è significava ABCDEFGHIJKLMNOPQRSTUVWXYZ e non le cose come Ý, Ê) fanno parte del set di caratteri portatile in modo da codificare la stessa in tutti i set di caratteri supportati sul sistema.
Per questo, quando si imposta la LC_CTYPEvariabile di localizzazione, che è quella che decide quali set di caratteri viene utilizzato e quali cose come blank, alphaclassi di personaggi contengono. Ma per la definizione dell'intervallo AZ, dovrai anche impostare la LC_COLLATEvariabile (quella che decide dell'ordinamento delle stringhe).
La locale Caka POSIXè quella che garantisce che i caratteri siano a byte singolo e AZ sia ABCDEFGHIJKLMNOPQRSTUVWXYZ. Potresti fare:
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(qui spostare la -fine, altrimenti, )-+sarebbe come un intervallo come A-Z)
Ma si noti che la LC_ALLvariabile sovrascrive tutti gli altri LC_*e LANGvariabili. Quindi, se LC_ALLaltrimenti è già definito, quanto sopra non avrà alcun effetto. Quindi invece puoi semplicemente fare:
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
Ciò influirà su altre cose come la lingua dei messaggi di errore, ma comunque, cambiare LC_CTYPE potrebbe già essere stato un problema per i messaggi di errore (ad esempio, nessun modo di esprimere messaggi di errore russo o giapponese nel set di caratteri della locale C).
xargs...