Ho un file di testo con le linee di testo UTF-8 codificato:Perché il testo UTF-8 ordina in ordine diverso tra OS X e Linux?
mac-os-x$ cat unsorted.txt
ウ
foo
チ
'foo'
津
In caso aiuta a riprodurre il problema, ecco un checksum e un dump dei byte esatto del file, così come come si potrebbe generare il file da soli (su Linux, utilizzare base64 -d
invece di -D
):
mac-os-x$ shasum unsorted.txt
a6d0b708d3e0cafb0c6e1af7450e9243da8cb078 unsorted.txt
mac-os-x$ perl -ne 'print join(" ", map { sprintf "%02x", ord } split //), "\n"' unsorted.txt
e3 82 a6 0a
66 6f 6f 0a
e3 83 81 0a
27 66 6f 6f 27 0a
e6 b4 a5 0a
mac-os-x$ echo 44KmCmZvbwrjg4EKJ2ZvbycK5rSlCg== | base64 -D > unsorted.txt
Quando ho risolvere la questione file di input su Mac OS X (indipendentemente dal fatto che io uso GNU ordinamento 5,93 che le navi di Mac OS X Yosemite con, o con una versione di ordinamento GNU installata in Homebrew 8.23), ottengo questo risultato ordinato:
mac-os-x$ env -i LANG=en_US.utf-8 LC_ALL=en_US.utf-8 /usr/bin/sort unsorted.txt
'foo'
foo
ウ
チ
津
mac-os-x$ echo `sw_vers -productName` `sw_vers -productVersion`
Mac OS X 10.10.1
mac-os-x$ /usr/bin/sort --version | head -1
sort (GNU coreutils) 5.93
Quando sono a ordinare lo stesso file, con le stesse impostazioni locali, su Linux (ho testato su entrambi CentOS 5.5 e CentOS 6.5), ottengo un risultato diverso:
linux-centos-6.5$ env -i LANG=en_US.utf-8 LC_ALL=en_US.utf-8 /bin/sort unsorted.txt
ウ
チ
foo
'foo'
津
linux-centos-6.5$ cat /etc/redhat-release
CentOS release 6.5 (Final)
linux-centos-6.5$ /bin/sort --version | head -1
sort (GNU coreutils) 8.4
Nota le diverse sedi del giapponese kana contro l'inglese e il diverso ordine tra due linee che differiscono solo dalle virgolette singole.
Per aggiungere un'altra variante al mix, ho notato che su un vecchio FreeBSD 6 scatola che ho, ho lo stesso tipo di ordinamento come OS X:
freebsd-6.0$ env -i LANG=en_US.utf-8 LC_ALL=en_US.utf-8 /usr/bin/sort unsorted.txt
'foo'
foo
ウ
チ
津
freebsd-6.0$ uname -rs
FreeBSD 6.0-RELEASE
freebsd-6.0$ sort --version | head -1
sort (GNU coreutils) 5.3.0-20040812-FreeBSD
mi aspettavo l'ordinamento di essere il lo stesso in ogni caso, dato che tutti i casi utilizzano l'ordinamento GNU, tutti con le stesse impostazioni locali. Ho provato esplicitamente a impostare LC_COLLATE
separatamente e ho provato a utilizzare LC_COLLATE=C
per forzare un ordinamento in base all'ordine dei byte, ma questo non ha modificato alcun risultato.
Perché il mio file di input di esempio viene ordinato in modo diverso su OS X e Linux? E come potrei forzare entrambi i sistemi a produrre testo identicamente ordinato (non mi interessa quale variante, purché sia coerente tra i due)?
'LC_ALL' sovrascrive' LC_ * '. https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Locale-Categories.html –
Sembra che l'impostazione LC_ALL = C faccia corrispondere l'ordine di ordinamento alla variante OS X e FreeBSD su Linux. In modo che risponda alla seconda parte della mia domanda (come potrei forzare entrambi i sistemi a produrre testo identicamente ordinato?). Sto ancora cercando di capire la prima parte della domanda: perché il file di input viene ordinato in modo diverso in un primo momento? Come ha sottolineato @CedricHan, il mio assunto che LC_COLLATE avrebbe vinto su LC_ALL ai fini dell'ordinamento era sbagliato; ma come posso duplicare l'ordinamento Linux sotto OS X? L'ordinamento –
utilizza le tabelle di confronto fornite dal sistema operativo.Se diversi SO forniscono tabelle di confronto diverse, otterrete risultati diversi. Non ha molto senso prevedere un particolare ordine di confronto per script non latini in un locale basato su inglese. 'ja_JP.UTF-8' ha un ordine di confronto diverso da' en_US.UTF-8', che è diverso da 'C'. –