Какое C
значение имеет для LC_ALL
Unix-подобных систем?
Я знаю, что это требует одного и того же языка для всех аспектов, но что делает C
?
environment-variables
locale
jcubic
источник
источник
xclock
warning (Missing charsets in String to FontSet conversion
), будет лучше, если вы будете использовать ее,LC_ALL=C.UTF-8
чтобы избежать проблем с кириллицей. Чтобы установить эту переменную среды, вы должны добавить следующую строку в конец~/.bashrc
файла -export LC_ALL=C.UTF-8
Ответы:
Это заставляет приложения использовать язык по умолчанию для вывода:
и заставляет сортировку быть побайтной:
источник
LC_ALL
переменная среды, которая переопределяет все остальные параметры локализации ( кроме$LANGUAGE
некоторых случаев ).Различные аспекты локализации (такие как разделитель тысяч или символ десятичной точки, набор символов, порядок сортировки, месяц, названия дня, сообщения о языке или приложении, такие как сообщения об ошибках, символ валюты) могут быть установлены с использованием нескольких переменных среды.
Как правило,
$LANG
вы выбираете значение, определяющее ваш регион (например,fr_CH.UTF-8
если вы говорите по-французски в Швейцарии, используя UTF-8). ОтдельныеLC_xxx
переменные переопределяют определенный аспект.LC_ALL
переопределяет их всех. Командаlocale
, когда вызывается без аргумента, дает сводку текущих настроек.Например, в системе GNU я получаю:
Я могу переопределить индивидуальную настройку, например:
Или же:
Или переопределить все с помощью LC_ALL.
В сценарии, если вы хотите принудительно установить конкретную настройку, так как вы не знаете, какие настройки принудительно задал пользователь (возможно, также и LC_ALL), ваш лучший, самый безопасный и обычно единственный вариант - принудительно использовать LC_ALL.
C
Локаль специальный язык , который предназначается , чтобы быть самым простым локали. Можно также сказать, что в то время как другие локали предназначены для людей, локаль C предназначена для компьютеров. В языке C символы - это одиночные байты, кодировка - ASCII (ну, не обязательно, но на практике это будет в системах, которые большинство из нас когда-либо получат), порядок сортировки основан на значениях байтов, язык обычно - американский английский (хотя для сообщений приложения (в отличие от таких вещей, как названия месяцев или дней или сообщения системных библиотек), это на усмотрение автора приложения), а такие вещи, как символы валют, не определены.В некоторых системах есть разница с языковым стандартом POSIX, где, например, порядок сортировки для символов, не относящихся к ASCII, не определен.
Обычно вы запускаете команду с LC_ALL = C, чтобы пользовательские настройки не мешали вашему сценарию. Например, если вы хотите
[a-z]
сопоставить 26 символов ASCII отa
toz
, вы должны установитьLC_ALL=C
.В системах GNU
LC_ALL=C
иLC_ALL=POSIX
(илиLC_MESSAGES=C|POSIX
) переопределения$LANGUAGE
покаLC_ALL=anything-else
не будет.Несколько случаев, когда вам обычно нужно установить
LC_ALL=C
:sort -u
илиsort ... | uniq...
. Во многих локалях, отличных от C, в некоторых системах (особенно в GNU) некоторые символы имеют одинаковый порядок сортировки .sort -u
не сообщает уникальные строки, но одну из каждой группы строк, имеющих одинаковый порядок сортировки. Поэтому, если вам нужны уникальные строки, вам нужен языковой стандарт, в котором символы являются байтовыми, а все символы имеют разный порядок сортировки (чтоC
гарантирует языковой стандарт).=
оператору POSIX-совместимогоexpr
или==
оператору POSIX-совместимогоawk
(mawk
иgawk
не POSIX в этом отношении), который не проверяет, идентичны ли две строки, но сортируют ли они одинаково.grep
. Если вы хотите сопоставить букву на языке пользователя, используйтеgrep '[[:alpha:]]'
и не изменяйтеLC_ALL
. Но если вы хотите сопоставитьa-zA-Z
символы ASCII, вам нужно либо либо,LC_ALL=C grep '[[:alpha:]]'
либоLC_ALL=C grep '[a-zA-Z]'
¹.[a-z]
соответствует символам, которые сортируются послеa
и доz
(хотя со многими API это сложнее). В других местах вы вообще не знаете, что это такое. Например, некоторые локали игнорируют регистр для сортировки, поэтому[a-z]
в некоторых API, таких какbash
шаблоны, можно включить[B-Z]
или[A-Y]
. Во многих локалях UTF-8 (в том числеen_US.UTF-8
в большинстве систем)[a-z]
будут указываться латинские буквы от иa
доy
с диакритическими знаками,z
посколькуz
что-то вроде них), что я не могу представить, было бы то, что вы хотите (почему вы хотите включить,é
а неź
?).арифметика с плавающей точкой в
ksh93
.ksh93
чтитdecimal_point
установку вLC_NUMERIC
. Если вы напишите скрипт, содержащийa=$((1.2/7))
его, он перестанет работать при запуске пользователем, в локали которого запятая используется в качестве десятичного разделителя:Тогда вам нужны такие вещи, как:
В качестве примечания:
,
десятичный разделитель конфликтует с,
арифметическим оператором, который может вызвать еще большую путаницу.grep '<.*>'
для поиска строк, содержащих a<
,>
пара не будет работать, если вы находитесь в локали UTF-8, а ввод кодируется в однобайтовом 8-битном наборе символов, например iso8859-15. Это потому, что.
только совпадающие символы и символы не ASCII в iso8859-15, скорее всего, не образуют действительный символ в UTF-8. С другой стороны,LC_ALL=C grep '<.*>'
будет работать, потому что любое значение байта формирует допустимый символ вC
локали.В любое время, когда вы обрабатываете входные данные или выходные данные, которые не предназначены для / для человека. Если вы разговариваете с пользователем, вы можете использовать его соглашение и язык, но, например, если вы сгенерируете некоторые числа для подачи в другое приложение, которое ожидает десятичные точки в английском стиле или названия месяцев на английском языке, вам нужно установить LC_ALL = C:
Это также относится к таким вещам, как сравнение без учета регистра (например, в
grep -i
) и преобразование регистра (awk
'stoupper()
,dd conv=ucase
...). Например:не гарантируется совпадение
I
в локали пользователя. В некоторых турецких районах , например, это делает не как верхний регистрi
являетсяİ
(обратите внимание на точку) там и строчнымI
естьı
(обратите внимание на недостающую точку).¹ В зависимости от кодировки текста это не всегда правильно. Это справедливо для UTF-8 или однобайтовых наборов символов (например, iso-8859-1), но не обязательно для многобайтовых наборов не-UTF-8.
Например, если вы находитесь в
zh_HK.big5hkscs
локали (Гонконг, использующий гонконгский вариант кодировки китайских символов BIG5), и вы хотите искать английские буквы в файле, закодированном в этих кодировках, выполните одно из следующих действий:или же
было бы неправильно, потому что в этой кодировке (и во многих других, но практически не использовавшихся после выхода UTF-8) многие символы содержат байты, соответствующие кодировке ASCII символов A-Za-z. Например, все
A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
(и многие другие) содержат кодировкуA
.䨝
0x96 0x41 иA
0x41 как в ASCII. Таким образом, нашLC_ALL=C grep '[a-zA-Z]'
код будет соответствовать тем строкам, которые содержат эти символы, поскольку он будет неправильно интерпретировать эти последовательности байтов.будет работать, но только если
LC_ALL
не установлено иное (что переопределяетLC_COLLATE
). Таким образом, вы можете в конечном итоге сделать:если вы хотите искать английские буквы в файле, закодированном в кодировке локали.
источник
C
локаль требуется только для поддержки «переносимого набора символов» (ASCII 0-127), а поведение для символов> 127 технически не определено . На практике большинство программ будут обрабатывать их как непрозрачные данные и передавать их, как вы описали. Но не все: в частности, Ruby может подавить данные char с байтами> 127, если работает вC
локали. Честно говоря, я не знаю, технически ли это «соответствует», но мы видели это в дикой природе .perl
и\x{7FFFFFFFFFFFFFFF}
), и в то время как диапазон кодовых точек Unicode был произвольно ограничен U + 10FFFF (из-за ограничений конструкции UTF-16) некоторые инструменты по-прежнему распознают / генерируют 6-байтовые символы. Вот что я имел в виду под 6-байтовыми символами. В семантике Unix один символ - это одна кодовая точка. Ваши более чем одна кодовая точка «символы» чаще всего обозначаются как графемные кластеры для устранения неоднозначности символов.C
это локаль по умолчанию, "POSIX" это псевдоним "C". Я думаю, "C" является производным от ANSI-C. Возможно, ANSI-C определит локаль "POSIX".источник
C
имя локали происходит от "ANSI C".Насколько я могу судить, OS X использует порядок сопоставления кодовых точек в локалях UTF-8, поэтому он является исключением из некоторых пунктов, упомянутых в ответе Стефана Шазеласа.
Это печатает 26 в OS X и 310 в Ubuntu:
Код ниже ничего не печатает в OS X, указывая, что вход отсортирован. Удаляемые шесть суррогатных символов вызывают ошибку недопустимой последовательности байтов.
Приведенный ниже код ничего не печатает в OS X, указывая, что нет двух последовательных кодовых точек (по крайней мере, между U + 000B и U + D7FF), которые имеют одинаковый порядок сопоставления.
(В приведенных выше примерах используется,
%b
потому чтоprintf \\U25
приводит к ошибке в Zsh.)Некоторые символы и последовательности символов, имеющие одинаковый порядок сопоставления в системах GNU, не имеют одинаковый порядок сопоставления в OS X. Это печатает сначала в OS X (используя OS X
sort
или GNUsort
), но сначала в Ubuntu:Это печатает три строки в OS X (используя OS X
sort
или GNUsort
), но одну строку в Ubuntu:источник
Похоже, что он также
LC_COLLATE
контролирует «алфавитный порядок», используемый ls. Язык США будет сортироваться следующим образом:в основном игнорируя периоды. Вы можете предпочесть:
Я конечно делаю. Настройка
LC_COLLATE
дляC
достижения этой цели. Обратите внимание, что он также будет сортировать строчные буквы после всех заглавных букв:источник