iconv를 사용하여 UTF-8을 MS-ANSI로 변환할 수 없는 이유는 무엇입니까?

iconv를 사용하여 UTF-8을 MS-ANSI로 변환할 수 없는 이유는 무엇입니까?

utf-8에서 ms-ansi로 파일을 변환하려고 합니다.

나는 사용한다

  iconv -f UTF8 -t MS-ANSI// < data.txt

하지만 얻을

  iconv: illegal input sequence at position 171359

이를 조사할 때

 dd if=data.txt of=error.txt bs=1 count=10 skip=171359

알겠어요:

 hexdump -C error.txt
 00000000  ef bb bf 38 3a 6e 61 09  38 3a                    |...8:na.8:|
 0000000a

파일이 utf-8이 아닙니다. 그렇지 않은 경우 대신 iconv를 사용해야 합니까?

답변1

$ printf '\xef\xbb\xbf' | uconv -x any-name
\N{ZERO WIDTH NO-BREAK SPACE}

이는 바이트 순서 표시로도 사용되는 문자(U+FEFF, 3바이트 UTF-8로 인코딩됨)입니다. 어떤 경우에도 해당 문자는 MS-ANSI에서 찾을 수 없으므로(때때로 windows-1252(iso8859-1의 상위 집합)에서 잘못된 이름이 지정됨) 해당 문자로 변환할 수 없습니다.

BOM은 UTF16-LE와 UTF16-BE(또는 CPU 엔디안의 영향을 받는 기타 비바이트 인코딩)를 구별하기 위해 일부 텍스트의 시작 부분에 사용됩니다. 바이트 순서 모호성이 없는 UTF-8에서는 의미가 없으며 단일 바이트 문자 집합 windows-1252에서는 더욱 그렇습니다. "너비가 0인 공백"이므로 표시되지 않으며 "0-너비 공백" 문자처럼 단어를 구분하는 속성이 없으므로 완전히 제거하는 것이 안전할 수 있습니다.

zsh, 또는 :bashksh93

sed $'s/\ufeff//g' < input | iconv -t windows-1252

일부 iconv구현의 경우 다음을 사용할 수도 있습니다.

iconv -t windows-1252//translit < input

//translit텍스트를 충실하게 번역할 수 없는 경우 근사치를 사용합니다. 이 경우 U+FEFF 문자만 제거됩니다.

$ printf '\xef\xbb\xbf\x38\x3a\x6e\x61\x09\x38\x3a' |
    iconv -t windows-1252//translit | hd
00000000  38 3a 6e 61 09 38 3a                              |8:na.8:|
00000007

또 다른 옵션은 다음을 사용하는 것입니다.

iconv -t utf-16le | iconv -f utf-16 -t windows-1252

첫 번째는 iconvBOM이 없는 UTF-16 리틀 엔디안으로 변환되지만 초기 U+FEFF는 BOM이 있는 실제 UTF-16으로 변환하므로 두 번째는 iconv섹션 순서라는 단어의 인코딩을 결정하는 데 사용되므로 해당 BOM을 제거합니다 utf-16.

관련 정보