"LC_ALL=C"는 무엇을 합니까?

"LC_ALL=C"는 무엇을 합니까?

CLC_ALLUnix 계열 시스템에서 의 가치는 어떤 역할을 합니까?

나는 그것이 모든 측면에서 동일한 로케일을 사용하도록 강제한다는 것을 알고 있지만 그것이 무엇을 합니까 C?

답변1

LC_ALL다른 모든 지역화 설정을 재정의하는 환경 변수입니다($LANGUAGE특정 상황을 제외하고).

일부 환경 변수를 사용하여 지역화의 다양한 측면(예: 천 단위 구분 기호 또는 소수점 문자, 문자 집합, 정렬 순서, 월, 요일 이름, 언어 또는 애플리케이션 메시지(예: 오류 메시지, 통화 기호))을 설정할 수 있습니다.

일반적으로 $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을 강제하는 것입니다.

locale은 C특별한 로케일이며, 가장 간단한 로케일입니다. 다른 로케일은 인간용이고 C 로케일은 컴퓨터용이라고 말할 수도 있습니다. C 로케일에서 문자는 단일 바이트이고 문자 세트는 ASCII(물론 필수는 아니지만 실제로 우리 대부분이 사용하는 시스템에 있을 것임)이며 정렬 순서는 바이트 값 1을 기반으로 하며 언어는 일반적으로 미국 영어입니다(애플리케이션 메시지의 경우(월이나 일 이름 또는 시스템 라이브러리의 메시지와 반대) 애플리케이션 작성자의 재량에 따라 다름) 통화 기호와 같은 것은 정의되지 않습니다.

일부 시스템에서는 비ASCII 문자에 대한 정렬 순서가 정의되지 않는 등 POSIX 로케일과 차이가 있습니다.

일반적으로 사용자 설정이 스크립트를 방해하지 않도록 하려면 LC_ALL=C로 명령을 실행합니다. 예를 들어 에서 까지 [a-z]26개의 ASCII 문자를 일치시키려면 이 항목을 설정해야 합니다 .azLC_ALL=C

GNU 시스템에서는 LC_ALL=CLC_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해당 문제는 POSIX mawk아님 ) 에도 동일하게 적용됩니다 .gawk

  • . 와 같은 문자 범위를 grep사용자 언어의 문자와 일치시키려면 를 사용 grep '[[:alpha:]]'하고 수정하지 마세요 LC_ALL. 그러나 ASCII 문자를 일치시키려면 or² 이 a-zA-Z필요합니다 . 전후 에 정렬된 문자 와 일치합니다(많은 API의 경우 상황이 이보다 더 복잡하지만). 다른 지역에서는 그것이 무엇인지 모르는 경우가 많습니다. 예를 들어 일부 로케일은 정렬 시 대/소문자를 무시하므로 일부 API(예: 스키마)에서는 또는 를 포함할 수 있습니다. 많은 UTF-8 로케일(대부분의 시스템 포함)에는 분음 부호가 있는 to부터의 라틴 문자가 포함되지만 분음 부호가 있는 문자는 포함되지 않습니다(그 이전에). 이것이 여러분이 원하는 것일 것이라고는 상상할 수 없습니다. 포함시키나요?)LC_ALL=C grep '[[:alpha:]]'LC_ALL=C grep '[a-zA-Z]'[a-z]az[a-z]bash[B-Z][A-Y]en_US.UTF-8[a-z]ayzzéź

  • 의 부동 소수점 연산 ksh93. 설정을 ksh93존중하십시오 . 포함된 스크립트를 작성하는 경우 로케일이 소수 구분 기호로 쉼표를 사용하는 사용자가 실행하면 작동이 중지됩니다.decimal_pointLC_NUMERICa=$((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 호환이라고 가정할 수 있습니다(거의 모든 문자 세트의 경우와 마찬가지로). 예를 들어, UTF-8 로케일에 있고 입력이 단일 바이트 8비트 문자 세트(예: iso8859-15)로 인코딩된 경우 , 쌍이 grep '<.*>'포함된 행을 찾는 것은 <작동하지 않습니다. iso8859-15에서 일치하는 문자, 비ASCII 문자만 UTF-8에서 유효한 문자를 형성하지 못할 가능성이 높기 >때문입니다 . .반면에 LC_ALL=C grep '<.*>'모든 바이트 값은 로케일에서 유효한 문자를 형성하기 때문에 작동합니다 C.

  • 언제든지 인간 또는 인간 이외의 기원이 아닌 입력 데이터 또는 출력 데이터를 처리합니다. 사용자와 대화하는 경우 사용자의 규칙과 언어를 사용하고 싶을 것입니다. 그러나 예를 들어 영어 스타일 소수점이나 영어 월 이름이 필요한 다른 응용 프로그램에 공급하기 위해 숫자를 생성하는 경우 다음을 원할 것입니다. 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이는 대소문자를 구분하지 않는 비교(예: in ) 및 대소문자 변환( awk's toupper(), ...) 에도 적용됩니다 dd conv=ucase. 예를 들어:

    grep -i i

I사용자 로케일의 일치는 보장되지 않습니다. 예를 들어, 일부 터키어 로케일에서는 대문자 i( İ점 참고) 및 소문자 I( ı누락된 점 참고) 처럼 보이지 않습니다 .


노트

다시 말하지만 이는 ASCII 기반 시스템(대부분의 시스템)에서만 작동합니다. POSIX strcoll()에서는 C 로케일의 === 최적화를 허용하지 않는 EBCDIC 시스템에서도 C 로케일의 조합 순서가 ASCII 문자 세트의 문자 순서가 되도록 요구합니다 .strcmp()


² 텍스트 인코딩에 따라 이것이 반드시 올바른 접근 방식이 아닐 수도 있습니다. 이는 UTF-8 또는 단일 바이트 문자 집합(예: iso-8859-1)에 작동하지만 UTF-8이 아닌 멀티바이트 문자 집합에는 반드시 그런 것은 아닙니다.

예를 들어, 특정 지역(BIG5 중국어 문자 인코딩의 홍콩 변형을 사용하는 홍콩)에 있고 zh_HK.big5hkscs해당 문자 세트로 인코딩된 파일에서 영어 문자를 찾으려는 경우 다음 중 하나를 수행합니다.

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

또는

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

해당 문자 세트(및 기타 많은 문자 세트(UTF-8 출현 이후 거의 사용되지 않음))에 많은 문자가 포함되어 있기 때문에 잘못된 것입니다.포함하다A-Za-z 문자에 해당하는 ASCII로 인코딩된 바이트입니다. 예를 들어 . 를 A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽포함하는 모든 것(및 그 이상) 은 0x96 0x41이며 이는 ASCII와 마찬가지로 0x41입니다. 따라서 이러한 바이트 시퀀스를 잘못 해석할 수 있으므로 이러한 문자가 포함된 행을 일치시킵니다.AALC_ALL=C grep '[a-zA-Z]'

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

작동하지만 LC_ALL달리 설정하지 않은 경우에만 가능합니다(이 값이 재정의됨 LC_COLLATE). 따라서 결국 다음을 수행해야 할 수도 있습니다.

grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'

로케일 인코딩으로 인코딩된 파일에서 영문자를 찾고 싶다면.


3 일부 사람들은 이제 유니코드 코드 포인트(및 UTF-8 데이터를 인코딩/디코딩하는 라이브러리)가 코드 포인트 U+0000 ~ U+10FFFF(0xD800 ~ 0xDFFF 제외)로 임의로 제한되었으므로 길이가 1 ~ 1이라고 주장합니다. UTF-16 인코딩을 수용하기 위해 U+7FFFFFFF부터 4바이트가 필요하지만 일부 애플리케이션에서는 여전히 6바이트 UTF-8 시퀀스(0xD800 .. 0xDFFF 범위에 속하는 시퀀스 포함)를 인코딩/디코딩할 수 있습니다.

답변2

이는 애플리케이션이 출력에 기본 언어를 사용하도록 강제합니다.

$ 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

답변3

C은 기본 로캘이고 "POSIX"는 "C"의 별칭입니다. "C"는 ANSI-C에서 파생된 것 같습니다. 아마도 ANSI-C는 "POSIX" 로케일을 정의할 수도 있습니다.

답변4

또한 LC_COLLATEls에서 사용하는 "알파벳순"을 제어하는 ​​것 같습니다. 미국 로캘은 다음과 같이 정렬됩니다.

a.C
aFilename.C
aFilename.H
a.H

마침표는 기본적으로 무시됩니다. 당신은 다음을 선호할 수도 있습니다:

a.C
a.H
aFilename.C
aFilename.H

당연히 알지. 이 작업을 완료 LC_COLLATE하려면 설정하세요 C. 모든 대문자 다음에 소문자도 정렬됩니다.

A.C
A.H
AFilename.C
a.C
a.H

관련 정보