Я работаю с огромными файлами текста (надеюсь) UTF-8. Я могу воспроизвести его с помощью Ubuntu 13.10 (3.11.0-14-generic) и 12.04.Как работают локали в Linux/POSIX и какие преобразования применяются?
Расследуя ошибку я столкнулся странно behavoir
$ export LC_ALL=en_US.UTF-8
$ sort part-r-00000 | uniq -d
ɥ ɨ ɞ ɧ 251
ɨ ɡ ɞ ɭ ɯ 291
ɢ ɫ ɬ ɜ 301
ɪ ɳ 475
ʈ ʂ 565
$ export LC_ALL=C
$ sort part-r-00000 | uniq -d
$ # no duplicates found
Дубликаты также появляются при выполнении пользовательского C++ программы, которая читает файл, используя C++, кажется, не затронут, по крайней мере, для std::stringstream
- это не удается из-дублей при использовании en_US.UTF-8
локаль.std::string
и ввода/вывода.
Почему дубликаты найдены при использовании языкового стандарта UTF-8, а дубликаты не найдены в локали C?
Какие преобразования приводят к языку текста, который вызывает это поведение?
Edit: Here небольшой пример
$ uniq -D duplicates.small.nfc
ɢ ɦ ɟ ɧ ɹ 224
ɬ ɨ ɜ ɪ ɟ 224
ɥ ɨ ɞ ɧ 251
ɯ ɭ ɱ ɪ 251
ɨ ɡ ɞ ɭ ɯ 291
ɬ ɨ ɢ ɦ ɟ 291
ɢ ɫ ɬ ɜ 301
ɧ ɤ ɭ ɪ 301
ɹ ɣ ɫ ɬ 301
ɪ ɳ 475
ͳ ͽ 475
ʈ ʂ 565
ˈ ϡ 565
Выход locale
когда появляется проблема:
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=de_DE.UTF-8
LC_TIME=de_DE.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_ALL=
Edit: После нормализации с помощью:
cat duplicates | uconv -f utf8 -t utf8 -x nfc > duplicates.nfc
Я до сих пор получаю такие же результаты
Edit: Файл действует UTF-8 в соответствии с iconv
- (от here)
$ iconv -f UTF-8 duplicates -o /dev/null
$ echo $?
0
Edit: Похоже, что-то похож на это: http://xahlee.info/comp/unix_uniq_unicode_bug.html и https://lists.gnu.org/archive/html/bug-coreutils/2012-07/msg00072.html
Он работает на FreeBSD
Это может помочь, если вы предоставили небольшой файл с фактическими строками, которые показывают другое поведение. Удалите строки до тех пор, пока вы не получите ровно одну пару строк, которые дублируются в локали en_US, а не в C. – Random832
Это файл в формате 1.1gb. Я изучаю это. –
Ну, во-первых, посмотрите, произойдет ли это в первых 10 000 строк или так (с помощью команды 'head') - или, может быть, grep для одного из символов, который появляется в одной из строк, выводимых uniq. – Random832