작업중 인 파일에서 찾은 이상한 캐릭터를 식별하려고합니다.
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
파일이 ISO-8859 인코딩을 사용하고 있으며 UTF-8로 변환 할 수 없습니다 :
$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text
내 주요 질문은 어떻게 od
여기 의 결과를 해석 할 수 있습니까? 내가 사용하려고 이 페이지 나 다른 문자 표현 사이에 변환 할 수 있습니다, 그러나 하더군요 005353
는 “16 진수 코드 포인트는”있는 그대로 卓
않는 오른쪽 보이지 0aeb
않는 “진수 코드 포인트”로 ૫
, 이는 다시, 잘못된 것 같습니다 .
그럼, 어떻게 내가 세 가지 옵션 중 하나를 사용하여 (수 355
, 005353
또는 0aeb
그들이 대표로되어있는 것을 문자 알아)?
그리고 네, 유니 코드 도구를 사용해 보았지만 유효한 UTF 문자가 아닌 것 같습니다.
$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
\pS \p{So}
All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode
유니 코드 U + FFFD 문자에 대한 설명을 이해하면 실제 문자가 아니며 손상된 문자의 자리 표시자가 아닙니다. 파일이 실제로 UTF-8로 인코딩되지 않았으므로 의미가 있습니다.
답변
파일에는 2 바이트의 EB와 0A가 16 진수로 들어 있습니다. 파일이 ISO-8859-1 과 같이 문자 당 1 바이트의 문자 세트를 사용하고있을 가능성이 있습니다 . 해당 문자 세트에서 EB는 다음과 같습니다.
$ printf "\353\n" | iconv -f ISO-8859-1
ë
다른 후보는 코드 페이지 437 에서 δ 이고 코드 페이지 850 에서 Ù입니다 .
od -x
이 경우 엔디안 (endianness)으로 인해 출력이 혼동됩니다. 더 나은 옵션은 -t x1
단일 바이트를 사용하는 것입니다.
$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002
od -x
od -t x2
한 번에 2 바이트를 읽는 맵을 작성하고 리틀 엔디안 시스템에서는 바이트를 역순으로 출력합니다.
UTF-8이 유효하지 않은 (또는 UTF-8 파일로 해석 될 때 의미가없는) 이와 같은 파일을 발견하면 자동으로 인코딩 (및 문자 세트)을 결정할 수있는 완벽한 방법이 없습니다. 컨텍스트는 도움이 될 수 있습니다. 지난 20 년 동안 Western PC에서 제작 된 파일 인 경우 ISO-8859-1, -15 (Euro 변형) 또는 Windows-1252로 인코딩 될 가능성이 높습니다. 그보다 오래된 경우 CP-437 및 CP-850이 후보가 될 수 있습니다. 동유럽 시스템, 러시아 시스템 또는 아시아 시스템의 파일은 내가 잘 모르는 다른 문자 집합을 사용합니다. 그런 다음 EBCDIC … iconv -l
가 있습니다. iconv
알고있는 모든 문자 세트가 나열되며, 여기에서 시행 착오를 진행할 수 있습니다.
(한 시점에서 나는 CP-437과 ATASCII의 대부분을 마음 속으로 알고 있었기 때문에 그 시절이었다.)
답변
주 od
에 대한 짧은 진수 덤프 때문에, 005353
8 진수 단어와 같은 2 바이트가는 od -x
것입니다 0aeb
단어로 진수, 그리고 파일의 실제 내용은 두 바이트 eb
및 0a
16 진수로,이 순서.
모두 그렇게 005353
하고 0aeb
그냥 “16 진수 코드 포인트”로 해석 할 수 없습니다.
0a
줄 바꿈 (LF)이며 eb
인코딩에 따라 다릅니다. file
인코딩을 추측하는 것이라면 무엇이든 될 수 있습니다. 파일 등의 추가 정보가 없으면 찾기가 어려울 것입니다.
답변
텍스트 파일의 문자 집합을 100 % 정확하게 추측 할 수는 없습니다.
명시적인 charset 정보가 정의되어 있지 않은 경우 chardet , firefox , file -i 와 같은 도구 (예 : HTML에 메타 charset = …가 포함 된 경우 상황이 더 쉬움)는 그렇지 않은 경우 휴리스틱을 사용하려고합니다. 텍스트가 충분히 큽니다.
다음에, 내가 가진 캐릭터 감지를 보여 chardet
( pip install chardet
/ apt-get install python-chardet
필요한 경우).
$ echo "in Noël" | iconv -f utf8 -t latin1 | chardet
<stdin>: windows-1252 with confidence 0.73
좋은 문자 세트 후보를 가지고 나면 iconv
, recode
또는 비슷한 것을 사용하여 파일 문자 세트를 “활성”문자 세트 (내 경우에는 utf-8)로 변경하고 올바르게 추측했는지 확인할 수 있습니다 …
iconv -f windows-1252 -t utf-8 file
iso-8859-3, iso-8859-1과 같은 일부 문자 세트에는 공통 문자가 많으며 때로는 완벽한 문자 세트를 찾았는지 쉽게 알 수 없습니다.
따라서 관련 텍스트 (예 : XML)와 관련된 메타 데이터를 갖는 것이 매우 중요합니다.
답변
#!/bin/bash
#
# Search in a file, a known (part of a ) String (i.E.: Begrüßung),
# by testing all encodings
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE fUnKy_CHAR_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//')
do
iconv -f $enc -t UTF-8 $FILE 2>/dev/null | grep -m 1 $PATTERN && echo $enc
done
Instance the Word Begrung이 들어있는 파일을 얻는다면 Begrüßung이 의미하는 것으로 추론 할 수 있습니다. 그래서 나는 모든 알려진 인코더로 그것을 변환하고, 그것이 발견되었는지, 그것이 올바르게 변환되는지 봅니다.
일반적으로 여러 가지 인코딩이 있습니다.
더 긴 파일의 경우 수백 페이지를 변환하는 대신 스 니펫을자를 수 있습니다.
그래서 나는 그것을 부를 것이다
encodingfinder.sh FILE Begrüßung
스크립트는 알려진 인코딩으로 변환하여 “Begrüßung”을 생성하는지 여부를 테스트합니다.
펑키 한 캐릭터가 종종 눈에 띄기 때문에 그러한 캐릭터를 찾으려면 일반적으로 도움이되지 않습니다. 문맥에서 검색 할 올바른 단어가 일반적으로 추론 될 수 있습니다. 그러나 우리는 hexeditor를 사용하여 바이트가 무엇인지 확인한 다음 끝없는 인코딩 테이블을 방문하여 범죄자를 찾습니다. 🙂