LC_ALL=C는 파괴적입니까?

LC_ALL=C는 파괴적입니까?

나는 상당히 큰(~15GB) 텍스트 파일 세트를 가지고 있습니다. 이러한 파일은 본질적으로 자격 증명을 포함하는 간단한 데이터베이스이며, 해당 파일의 자격 증명은 종종 128자 ASCII 범위(악센트 문자 등)를 벗어나는 경우가 있습니다.

이 파일 중 일부를 다음과 같이 정렬하려고 할 때:

sort -u input.txt -o output.txt

...다음 오류가 발생합니다.

sort: string comparison failed: Invalid or incomplete multibyte or wide character
sort: Set LC_ALL='C' to work around the problem.

나는 를 사용하여 및 LC_ALL=C같은 문자를 처리하는 명령의 속도를 높이는 방법 에 대해 많이 읽었습니다 .sortgrep스테판 차젤라스의 훌륭한 답변주제에 대해서는 특히 데이터 세트에 사용하면 어떤 영향을 미칠지 걱정됩니다.

이러한 파일을 실행하면 LC_ALL=C sort -uASCII가 아닌 문자가 제거될 가능성이 있습니까?

그렇다면, 그러면 대신에 모든 항목을 수정/제거하기 위해 할 수 있는 작업은 무엇입니까?유효하지 않거나 불완전한 멀티바이트 또는 와이드 문자"를 사용하지 않고도 파일을 정렬할 수 있습니다 LC_ALL=C.

답변1

이 파일에서 LC_ALL=C sort -u를 실행하면 ASCII가 아닌 문자가 제거될 가능성이 있습니까?

이 경우에는 아닙니다. sort바이트 값을 문자로 변환하는 대신 바이트 값에 대해 직접 작업합니다.

그러나 다른 도구에도 반드시 동일하게 적용되는 것은 아닙니다. C(언어)로 작성된 프로그램은 이런 방식으로 동작할 가능성이 가장 높습니다. Python 3과 같이 강력한 바이트 대 문자 구별이 있는 언어로 작성된 프로그램은 문자 세트를 따르지 않는 입력을 받아들이는 것을 완전히 거부해야 합니다. 그리고 오류를 무시하고 대신 � 또는 a를 출력하는 잘못 작성된 프로그램을 상상할 수도 있습니다 ?.

그렇다면 이 파일에서 "잘못되거나 불완전한 멀티바이트 또는 와이드 문자"를 모두 수정/제거하여 LC_ALL=C를 사용하지 않고 정렬할 수 있도록 하려면 어떻게 해야 합니까?

모두 동일한 파일 인코딩(UTF-8 권장)을 사용하고 있는지, 로캘이 동일한 인코딩을 사용하고 있는지 확인하세요. 크기에 관계없이 유효한 UTF-8 파일에 대해서는 오류가 발생해서는 안됩니다.

답변2

sort, grep, awkwc와 같은 다양한 Bash 도구를 통해 내 파일을 파이프해야 했기 때문에 tr허용된 답변에 표시된 "적절한 솔루션"을 선택하는 것이 더 안전하다고 결정했습니다. 먼저 모두 UTF-8로 변환합니다. 이것은 예상보다 조금 더 어려워졌습니다. 특히 file파일이 ASCII인지 UTF-8인지 결정하는 것이 신뢰할 수 없다는 것을 깨닫는 데 시간이 걸렸기 때문입니다(파일 전체를 확인하지 않기 때문입니다). 그래서 나는 후손을 위해 이 답변을 여기에 올려 놓았습니다.

파일의 인코딩을 확실하게 확인하려면 먼저 uchardet패키지가 Cygwin 설치 프로그램을 통해 설치되었는지 확인하십시오.적절한-cyg, 다음을 실행합니다.

uchardet *.txt

또는 Cygwin을 사용하지 않는 경우:

chardet *.txt 

chardet나열된 모든 파일을 ASCII자체 폴더로 이동하고 for해당 폴더에서 다음 루프를 실행합니다.

for i in *.txt; do iconv -f ASCII -t UTF-8 "$i" >> "${i%.txt}_utf.txt"; done;

.txt폴더의 모든 파일을 반복 하고 utf접미사가 추가된 UTF-8 버전을 생성합니다.

다시 실행하면 uchardet *.txt일부 파일이 여전히 ASCII. 이는 ASCII가 UTF-8의 하위 집합이고단순히 의미해당 파일에는 128비트의 ASCII 범위를 벗어나는 문자가 포함되어 있지 않습니다.

sort이제 를 사용하지 않고도 실행할 수 있습니다 LC_ALL=C.

관련 정보