Что делает «LC_ALL = C»?

Что делает значение C для LC_ALL в Unix-подобных системах?

Я знаю, что он заставляет ту же локаль для всех аспектов, но что делает C ?

  • Как мне сначала сделать символы подчеркивания ls?
  • Почему я не могу правильно найти Debian 8.1 на моем BeagleBone Black?
  • Linux говорит по-английски, hpux italian, почему?
  • Поиск локалей без отдельной записи в / usr / share / locale на Debian
  • Как получить gnome-терминал на английском языке?
  • Unicode emoji не отображается в подсказке tcsh
  • Установка языка для выполнения одной программы
  • Как я могу сначала показать «ls» dotfiles, оставаясь без учета регистра?
  • 5 Solutions collect form web for “Что делает «LC_ALL = C»?”

    Это заставляет приложения использовать язык по умолчанию для вывода и принудительно сортировать сортировку.

     $ LC_ALL=es_ES man ¿Qué página de manual desea? $ LC_ALL=C man What manual page do you want? $ LC_ALL=en_US sort <<< $'a\nb\nA\nB' a A b B $ LC_ALL=C sort <<< $'a\nb\nA\nB' A B a b 

    LC_ALL – это переменная среды, которая переопределяет все другие параметры локализации ( за исключением $LANGUAGE при некоторых обстоятельствах ).

    Различные аспекты локализации (например, символ разделителя тысяч или десятичная точка, набор символов, порядок сортировки, месяц, имена дней, сообщения языка или приложения, такие как сообщения об ошибках, символ валюты) могут быть установлены с использованием нескольких переменных окружения.

    Обычно вы fr_CH.UTF-8 $LANG своим предпочтениям со значением, которое идентифицирует ваш регион (например, fr_CH.UTF-8 если вы находитесь на франкоговорящей Швейцарии, используя UTF-8). Отдельные переменные LC_xxx переопределяют определенный аспект. LC_ALL переопределяет их все. Команда locale при вызове без аргумента дает сводку текущих настроек.

    Например, в системе GNU я получаю:

     $ locale LANG=en_GB.UTF-8 LANGUAGE= LC_CTYPE="en_GB.UTF-8" LC_NUMERIC="en_GB.UTF-8" LC_TIME="en_GB.UTF-8" LC_COLLATE="en_GB.UTF-8" LC_MONETARY="en_GB.UTF-8" LC_MESSAGES="en_GB.UTF-8" LC_PAPER="en_GB.UTF-8" LC_NAME="en_GB.UTF-8" LC_ADDRESS="en_GB.UTF-8" LC_TELEPHONE="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" LC_IDENTIFICATION="en_GB.UTF-8" LC_ALL= 

    Я могу переопределить индивидуальные настройки, например:

     $ LC_TIME=fr_FR.UTF-8 date jeudi 22 août 2013, 10:41:30 (UTC+0100) 

    Или:

     $ LC_MONETARY=fr_FR.UTF-8 locale currency_symbol € 

    Или переопределите все с помощью LC_ALL.

     $ LC_ALL=C LANG=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8 cat / cat: /: Is a directory 

    В сценарии, если вы хотите принудительно установить определенный параметр, так как вы не знаете, какие параметры принудительно принудительно (возможно, LC_ALL), ваш лучший, самый безопасный и обычно единственный вариант – заставить LC_ALL.

    Локаль C – это особый язык, который должен быть простейшим языком. Вы могли бы также сказать, что, в то время как другие локали для людей, языковой стандарт C предназначен для компьютеров. В языке C символы являются одиночными байтами, кодировка – ASCII (ну, это не требуется, но на практике это будет в системах, которые большинство из нас когда-либо будет использовать), порядок сортировки основан на байтовых значениях, язык обычно является английским (хотя для сообщений приложений (в отличие от таких, как имена месяца или дня или сообщения из системных библиотек) это зависит от автора приложения), и такие вещи, как символы валюты, не определены.

    В некоторых системах существует разница с языковой версией POSIX, где, например, порядок сортировки для символов, отличных от ASCII, не определен.

    Обычно вы выполняете команду с LC_ALL = C, чтобы избежать того, чтобы настройки пользователя мешали вашему скрипту. Например, если вы хотите, чтобы [az] соответствовал 26 символам ASCII от a до z , вы должны установить 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... sort ... | uniq... Во многих локалях, отличных от C, в некоторых системах (особенно в GNU) некоторые символы имеют одинаковый порядок сортировки . sort -u не сообщает уникальные строки, а одну из каждой группы строк, которые имеют равный порядок сортировки. Поэтому, если вам нужны уникальные строки, вам нужна локаль, где символы являются байтами, а все символы имеют разный порядок сортировки (что гарантирует языковой стандарт C ).
    • то же самое относится к оператору = оператора POSIX-совместимого оператора expr или == совместимого с POSIX awk s ( mawk и gawk не являются POSIX в этом отношении), которые не проверяют, идентичны ли две строки, независимо от того, сортируются ли они одинаково.
    • Диапазоны символов, например, в grep . Если вы хотите LC_ALL букву на языке пользователя, используйте grep '[[:alpha:]]' и не изменяйте LC_ALL . Но если вы хотите a-zA-Z символы a-zA-Z ASCII, вам нужно либо LC_ALL=C grep '[[:alpha:]]' либо LC_ALL=C grep '[a-zA-Z]' ¹. [az] соответствует символам, которые сортируются после a и до z (хотя со многими API-интерфейсами это сложнее, чем это). В других местах вы вообще не знаете, что это такое. Например, некоторые локали игнорируют регистр для сортировки, поэтому [az] в некоторых API, таких как шаблоны bash , могут включать [BZ] или [AY] . Во многих локалях UTF-8 (в том числе en_US.UTF-8 в большинстве систем), [az] будет включать латинские буквы от a до y с диакритикой, но не те из z (поскольку z сортирует перед ними), которые я не могу себе представить будет то, что вы хотите (зачем вы хотите включить é а не ź ?).
    • арифметика с плавающей запятой в ksh93 . ksh93 decimal_point значение decimal_point в LC_NUMERIC . Если вы пишете скрипт, содержащий a=$((1.2/7)) , он перестанет работать при запуске пользователем, чья локаль имеет запятую в качестве десятичного разделителя:

       $ ksh93 -c 'echo $((1.1/2))' 0.55 $ LANG=fr_FR.UTF-8 ksh93 -c 'echo $((1.1/2))' ksh93: 1.1/2: arithmetic syntax error 

      Тогда вам нужны такие вещи, как:

       #! /bin/ksh93 - float input="$1" # get it as input from the user in his locale float output arith() { typeset LC_ALL=C; (($@)); } arith output=input/1.2 # use the dot here as it will be interpreted # under LC_ALL=C echo "$output" # output in the user's locale 

      В качестве побочного примечания: разделитель с десятичной запятой конфликтует с арифметическим оператором, который может вызвать еще большую путаницу.

    • Когда вам нужны символы для байтов. В настоящее время большинство локалей основаны на UTF-8, что означает, что символы могут занимать от 1 до 6 байтов. При работе с данными, которые должны быть байтами, с текстовыми утилитами, вы должны установить LC_ALL = C. Это также значительно улучшит производительность, потому что анализ данных UTF-8 имеет стоимость.
    • Следствие предыдущего пункта: при обработке текста, где вы не знаете, какой символ задает вход, записывается, но может предполагать, что он совместим с ASCII (как и практически все кодировки). Например, grep '<.*>' Для поиска строк, содержащих пару < , > , не будет работать, если вы находитесь в локали UTF-8, а вход кодируется в однобайтном 8-битном наборе символов, например iso8859- 15. Это потому, что . только символы совпадений и символы, отличные от ASCII в iso8859-15, скорее всего, не образуют допустимого символа в UTF-8. С другой стороны, LC_ALL=C grep '<.*>' Будет работать, потому что любое значение байта формирует допустимый символ в локали C
    • Каждый раз, когда вы обрабатываете входные данные или выходные данные, которые не предназначены для / для человека. Если вы разговариваете с пользователем, вы можете использовать их соглашение и язык, но, например, если вы генерируете некоторые цифры для подачи какого-либо другого приложения, которое ожидает десятичные точки английского стиля или английские месячные имена, вы захотите set LC_ALL = C:

       $ printf '%g\n' 1e-2 0,01 $ LC_ALL=C printf '%g\n' 1e-2 0.01 $ date +%b août $ LC_ALL=C date +%b Aug 

      Это также относится к таким ситуациям, как нечувствительность к регистру (например, в grep -i ) и преобразование case ( awk 's toupper() , dd conv=ucase …). Например:

       grep -ii 

      не может совпадать с I в пользовательской локали. Например, в некоторых турецких локалях это не так, как верхний регистр i – это İ (обратите внимание на точку), а нижний регистр Iı (обратите внимание на отсутствующую точку).


    ¹ В зависимости от кодировки текста это не всегда правильно. Это справедливо для UTF-8 или однобайтовых наборов символов (например, iso-8859-1), но не обязательно для многобайтовых наборов символов, отличных от UTF-8.

    Например, если вы находитесь в zh_HK.big5hkscs locale (Гонконг, используя вариант Гонконга кодировки китайского символа BIG5), и вы хотите искать английские буквы в файле, закодированном в этих кодировках, либо выполните:

     LC_ALL=C grep '[[:alpha:]]' 

    или

     LC_ALL=C grep '[a-zA-Z]' 

    было бы неправильно, потому что в этой кодировке (и многие другие, но вряд ли использовались после выхода UTF-8), многие символы содержат байты, которые соответствуют кодировке ASCII символов A-Za-z. Например, все A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽 (и многие другие) содержат кодировку A – 0x96 0x41, а A – 0x41, как в ASCII. Таким образом, наш LC_ALL=C grep '[a-zA-Z]' будет совпадать с теми строками, которые содержат эти символы, так как это неверно интерпретирует эти последовательности байтов.

     LC_COLLATE=C grep '[A-Za-z]' 

    будет работать, но только если LC_ALL в противном случае не задан (что бы переопределить LC_COLLATE ). Таким образом, вам может понадобиться сделать:

     grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]' 

    если вы хотите искать английские буквы в файле, закодированном в кодировке локали.

    Насколько я могу судить, OS X использует порядок сортировки кодовой точки в локалях UTF-8, поэтому это исключение из некоторых пунктов, упомянутых в ответе Стефана Чазеласа.

    Это отображает 26 в OS X и 310 в Ubuntu:

     export LC_ALL=en_US.UTF-8 printf %b $(printf '\\U%08x\\n' $(seq $((0x11)) $((0x10ffff))))|grep -a '[az]'|wc -l 

    В приведенном ниже коде ничего не отображается в OS X, указывая, что вход сортируется. Шесть суррогатных символов, которые удаляются, вызывают неправильную ошибку последовательности байтов.

     export LC_ALL=en_US.UTF-8 for ((i=1;i<=0x1fffff;i++));do x=$(printf %04x $i) [[ $x = @(000a|d800|db7f|db80|dbff|dc00|dfff) ]]&&continue printf %b \\U$x\\n done|sort -c 

    В приведенном ниже коде ничего не отображается в OS X, что указывает на отсутствие двух последовательных кодовых точек (по крайней мере, между U + 000B и U + D7FF), которые имеют один и тот же порядок сортировки.

     export LC_ALL=en_US.UTF-8 for ((i=0xb;i<=0xd7fe;i++));do printf %b $(printf '\\U%08x\\n' $((i+1)) $i)|sort -c 2>/dev/null&&echo $i done 

    (В приведенных выше примерах используется %b потому что printf \\U25 приводит к ошибке в zsh.)

    Некоторые символы и последовательности символов, которые имеют один и тот же порядок сортировки в системах GNU, не имеют того же порядка сортировки в OS X. Это печатает ① сначала в OS X (используя sort OS X или GNU), но ② сначала в Ubuntu:

     export LC_ALL=en_US.UTF-8;printf %s\\n ② ①|sort 

    Это печатает три строки в OS X (используя sort OS X или sort GNU), но одна строка в Ubuntu:

     export LC_ALL=en_US.UTF-8;printf %b\\n \\u0d4c \\u0d57 \\u0d46\\u0d57|sort -u 

    Похоже, что LC_COLLATE управляет «алфавитным порядком», используемым ls. Языковой стандарт США будет сортироваться следующим образом:

     aC aFilename.C aFilename.H aH 

    в основном игнорируя периоды. Вы можете предпочесть:

     aC aH aFilename.C aFilename.H 

    Конечно. Установка LC_COLLATE на C выполняет это. Обратите внимание, что он также будет сортировать строчные буквы после всех капиталов:

     AC AH AFilename.C aC aH 

    C является стандартным языком, «POSIX» является псевдонимом «C». Я думаю, что «C» происходит от ANSI-C. Возможно, ANSI-C определяет локаль POSIX.

    Linux и Unix - лучшая ОС в мире.