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, UTF-8의 3바이트로 인코딩됨)입니다. 어떤 경우에도 해당 문자는 MS-ANSI(iso8859-1의 상위 집합인 windows-1252에 가끔 제공되는 부적절한 이름)에서 찾을 수 없으므로 해당 문자로 변환할 수 없습니다.

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.

관련 정보