#1 16-05-2016 07:48:26

marcomotta
Fedora nel sangue
Da Roma
Registrato: 18-01-2009
Messaggi: 2'530
Sito web

Bug di sort e uniq? Strani effetti con UTF8

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' | sort

±
∅
∞
∅
∓

(Il carattere "insieme vuoto" non viene ordinato rispetto a "infinito")

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' | sort | uniq

±
∅

Qui il carattere "infinito" scompare dall'output (stesso risultato con sort -u).

Secondo voi è un bug da segnalare?


Edit: sicuramente la colpa non è di sed:

$ (echo "∅"; echo "∞"; echo "∅") | sort
∅
∞
∅

Ultima modifica di marcomotta (16-05-2016 07:56:07)


La filosofia è una disciplina con obiettivi, ma senza regole. La matematica è una disciplina con regole, ma senza obiettivi.
Un giorno ho incontrato un uomo che non aveva né obiettivi né regole. Studiava filosofia della matematica.

Non in linea

#2 16-05-2016 08:53:47

frafra
Fedora Ambassador
Da Vignate
Registrato: 14-05-2014
Messaggi: 1'453
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

Si, secondo me è un bug. Pare che solo ± venga riordinato.

Non in linea

#3 16-05-2016 09:03:45

marcomotta
Fedora nel sangue
Da Roma
Registrato: 18-01-2009
Messaggi: 2'530
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

Sì, è come se "∅" (8709, ovvero 0x2205) e "∞" (8734, ovvero 0x221e) vengano considerati lo stesso carattere...
Aperta segnalazione di bug.

Edit: forse la cosa è nota; infatti leggo nel sorgente sort.c:

/* FIXME: None of these tables work with multibyte character sets.
   Also, there are many other bugs when handling multibyte characters.
   One way to fix this is to rewrite 'sort' to use wide characters
   internally, but doing this with good performance is a bit
   tricky.  */

Ultima modifica di marcomotta (16-05-2016 09:20:00)


La filosofia è una disciplina con obiettivi, ma senza regole. La matematica è una disciplina con regole, ma senza obiettivi.
Un giorno ho incontrato un uomo che non aveva né obiettivi né regole. Studiava filosofia della matematica.

Non in linea

#4 16-05-2016 13:25:47

frafra
Fedora Ambassador
Da Vignate
Registrato: 14-05-2014
Messaggi: 1'453
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

Nel frattempo puoi usare qualcosa tipo:

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' |
    python3 -c"import sys;print(*sorted(sys.stdin),end='',sep='')"

...oppure, se preferisci Python 2:

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' |
    python -c'from sys import *;map(stdout.write,sorted(stdin))'

Per curiosità: come hai scoperto questo strano comportamento?

Non in linea

#5 16-05-2016 14:00:19

marcomotta
Fedora nel sangue
Da Roma
Registrato: 18-01-2009
Messaggi: 2'530
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

frafra ha scritto:

Per curiosità: come hai scoperto questo strano comportamento?

Ho una serie di files in java (+ qualche xml), e mi è venuta la curiosità di vedere quali caratteri non ascii erano presenti; inoltre, volevo vedere se avevo già inserito in qualche commento il simbolo dell'insieme vuoto per fare copia-incolla. Ho dato un

$ find /path/di/lavoro -name "*.java" -or -name "*.xml" | while read FILE; do cat "$FILE" | sed -e 's/\(.\)/\1\n/g'; done | sort | uniq | tr -d ' -~\n'; echo

e "∅" non c'era. L'ho copiato da una pagina web, salvato il file, ripetuto il comando, e... è sparito il simbolo "∞" dall'output! Da lì ho cominciato a fare qualche test...


N.B. Non credo che python possa servire nel mio caso, perchè la rimozione dei duplicati con uniq soffre dello stesso bug da cui è affetto sort... e non posso certo stampare diversi mega di caratteri ripetuti...

Ultima modifica di marcomotta (16-05-2016 14:08:02)


La filosofia è una disciplina con obiettivi, ma senza regole. La matematica è una disciplina con regole, ma senza obiettivi.
Un giorno ho incontrato un uomo che non aveva né obiettivi né regole. Studiava filosofia della matematica.

Non in linea

#6 16-05-2016 17:26:55

frafra
Fedora Ambassador
Da Vignate
Registrato: 14-05-2014
Messaggi: 1'453
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

Con Python puoi ottenere gli elementi doppi:

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' |
    python3 -c"import fileinput as f;i=list(f.input());print(set((l for l in i if i.count(l)>1)))"

Volendo puoi usare globstar al posto del find:

$ (shopt -s globstar
for file in in $path/**/*.{xml,java}; do
    # codice
done)

Non in linea

#7 16-05-2016 17:58:14

marcomotta
Fedora nel sangue
Da Roma
Registrato: 18-01-2009
Messaggi: 2'530
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

frafra ha scritto:

Con Python puoi ottenere gli elementi doppi:

$ echo "±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' |
    python3 -c"import fileinput as f;i=list(f.input());print(set((l for l in i if i.count(l)>1)))"

Non sembra affidabile (oltre a riportare parentesi graffe, apici e virgole, in stile stampa di lista python):

$ echo "abderaaaaa±∅∞∅∓" | sed -e 's/\(.\)/\1\n/g' | python3 -c"import fileinput as f;i=list(f.input());print(set((l for l in i if i.count(l)>1)))"
{'∅\n', 'a\n'}

Forse funziona così:

$ echo "±∅∞∅∓aabcd" | sed -e 's/\(.\)/\1\n/g' | python3 -c"import fileinput as f;i=list(f.input());print(''.join(set(l for l in i)))" | tr -d '$\n'; echo
a∅d∞bc±∓

Quindi:

$ find $PATH_FILES -name "*.java" -or -name "*.xml" | while read FILE; do cat "$FILE" | sed -e 's/\(.\)/\1\n/g'; done | python3 -c"import fileinput as f;i=list(f.input());print(''.join(set(l for l in i)))" | tr -d ' -~\n'; echo
ù≠πü³éγÁôáìÈó≥ΔÉ∞Σβªθ¹°Óδ²·¡à¿∅αò±∓èÚÍ≤εíú§ñ

Ultima modifica di marcomotta (16-05-2016 17:59:01)


La filosofia è una disciplina con obiettivi, ma senza regole. La matematica è una disciplina con regole, ma senza obiettivi.
Un giorno ho incontrato un uomo che non aveva né obiettivi né regole. Studiava filosofia della matematica.

Non in linea

#8 16-05-2016 21:34:23

frafra
Fedora Ambassador
Da Vignate
Registrato: 14-05-2014
Messaggi: 1'453
Sito web

Re: Bug di sort e uniq? Strani effetti con UTF8

Se togli la parte finale dell'if non funziona correttamente.
Detto ciò, ho riletto il tuo messaggio precedente e recepito le tue nuove osservazioni. Ho provato a scrivere qualcosa di meglio.

$ echo "abderaaaaa±∅∞∅∓" | python3 -c"import fileinput as f;print(*set(filter(lambda c:ord(c)>127,''.join(f.input()))),sep='\n')"
±
∓
∅
∞

La cosa carina è che puoi passargli caratteri sia via pipe sia via file.

$ python3 -c"import fileinput as f;print(*set(filter(lambda c:ord(c)>127,''.join(f.input()))),sep='\n')" ~frafra/Documenti/*.txt
€
è
à

Di conseguenza, nel tuo caso suggerirei di lanciare:

$ (shopt -s globstar;
python3 -c"import fileinput as f;print(*set(filter(lambda c:ord(c)>127,''.join(f.input()))),sep='\n')" $PATH_FILES/**/*.{java,xml})

Siccome potrebbero esserci caratteri non utf-8 (raro, ma accade), per semplicità, al posto di complicare la vita a Python, potresti usare il buon iconv (che se vede qualcosa che non gli piace lo ignora):

$ (shopt -s globstar;cat $PATH_FILES/**/*.{java,xml}|iconv -tutf-8|
python3 -c"import fileinput as f;print(*set(filter(lambda c:ord(c)>127,''.join(f.input()))),sep='\n')")

Se ti interessasse anche l'ordinamento...

$ (shopt -s globstar;cat $PATH_FILES/**/*.{java,xml}|iconv -tutf-8|
python3 -c"import fileinput as f;print(*sorted(set(filter(lambda c:ord(c)>127,''.join(f.input())))),sep='\n')")

Non in linea

Piè di pagina