작업 중인 파일에서 발견된 이상한 문자를 식별하려고 합니다.
$ 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
"16진수 코드 포인트"가 ૫
잘못된 것 같다는 것을 알려줍니다 .
그렇다면 세 가지 옵션( 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로 인코딩되지 않았기 때문에 이는 의미가 있습니다.
답변1
파일에는 16진수로 EB와 0A라는 두 바이트가 포함되어 있습니다. 파일은 문자당 1바이트의 문자 세트를 사용할 수 있습니다.ISO-8859-1;이 문자 집합에서 EB는 ë입니다.
$ printf "\353\n" | iconv -f ISO-8859-1
ë
다른 후보는 δ코드페이지 437, Ù in코드 페이지 850...
od -x
이 경우 엔디안으로 인해 출력이 혼동됩니다. 더 나은 옵션은 -t x1
단일 바이트를 사용하는 것입니다.
$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002
od -x
od -t x2
한 번에 2바이트를 읽고 리틀 엔디안 시스템에서 바이트를 역순으로 출력하는 것으로 매핑됩니다 .
이와 같이 유효한 UTF-8이 아닌(또는 UTF-8 파일로 해석할 때 의미가 없는) 파일을 발견하는 경우 해당 인코딩(및 문자 집합)을 자동으로 결정하는 확실한 방법은 없습니다. 컨텍스트가 도움이 될 수 있습니다. 지난 수십 년 동안 서부 PC에서 생성된 파일인 경우 ISO-8859-1, -15(유럽 변형) 또는 Windows-1252로 인코딩되었을 가능성이 높습니다. 그보다 오래된 경우 CP입니다. -437과 CP-850이 가능한 후보이다. 동유럽 시스템, 러시아 시스템 또는 아시아 시스템의 파일은 제가 잘 이해할 수 없는 다른 문자 세트를 사용합니다. 그런 다음 EBCDIC...은 iconv -l
알려진 모든 문자 집합을 나열 iconv
하고 거기에서 몇 가지 시행착오를 수행할 수 있습니다.
(한때 CP-437과 ATASCII를 대부분 외웠어요. 그때가 그랬어요.)
답변2
od
줄임말 이니 참고하세요옥탈 덤프, 005353
8진수 단어인 2바이트, od -x
단어 0aeb
인 16진수, 파일의 실제 내용은 이 순서대로 2바이트 eb
와 16진수입니다.0a
따라서 005353
및 는 0aeb
"16진수 코드 포인트"로 해석될 수 없습니다.
0a
eb
인코딩에 따라 개행 문자(LF)입니다 . file
인코딩만 추측하면 무엇이든 될 수 있습니다. 파일의 출처 등 추가 정보가 없으면 찾기가 어렵습니다.
답변3
텍스트 파일의 문자 집합을 100% 정확하게 추측하는 것은 불가능합니다.
유사한 도구샤다이,파이어폭스 브라우저,파일-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
좋은 후보 문자 집합을 얻은 후 파일 문자 집합을 "활성" 문자 집합(내 경우에는 utf-8)으로 변경하는 데 사용하거나 iconv
유사한 방법을 사용하고 올바르게 추측되는지 확인할 수 있습니다.... ..recode
iconv -f windows-1252 -t utf-8 file
일부 문자 세트(예: iso-8859-3, iso-8859-1)에는 공통된 문자가 많습니다. 때로는 완벽한 문자 세트를 찾았는지 확인하기 어렵습니다.
따라서 관련 텍스트(예: XML)와 연결된 메타데이터를 갖는 것이 중요합니다.
답변4
#!/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
예를 들어 Begrung이라는 단어가 포함된 파일을 얻으면 아마도 Begrüßung을 의미한다고 추론할 수 있습니다. 그래서 알려진 모든 인코딩을 통해 변환하고 올바르게 변환되는 인코딩을 찾았는지 확인합니다.
종종 적절해 보이는 여러 인코딩이 있습니다.
더 긴 파일의 경우 수백 페이지를 변환하는 대신 단일 세그먼트를 잘라낼 수 있습니다.
그래서 나는 그것을 부를 것이다.
encodingfinder.sh FILE Begrüßung
스크립트는 "Begrüßung"을 생성하는 알려진 인코딩을 사용하여 변환할지 여부를 테스트합니다.
이와 같은 캐릭터를 찾으려면 건방진 캐릭터가 눈에 띄는 경향이 있기 때문에 조금 덜 도움이 됩니다. 일반적으로 문맥을 통해 검색할 올바른 단어를 추론할 수 있습니다. 그러나 우리는 이것이 어떤 바이트인지 확인하고 범인을 찾기 위해 끝없는 인코딩 테이블에 액세스하기 위해 16진수 편집기를 사용하고 싶지 않습니다. :)