Linux에서 스크립트를 통해 파일 인코딩을 찾는 방법은 무엇입니까?


303

디렉토리에있는 모든 파일의 인코딩을 찾아야합니다. 사용 된 인코딩을 찾는 방법이 있습니까?

file명령은이 작업을 수행 할 수 없습니다.

관심있는 인코딩은 ISO-8859-1입니다. 인코딩이 다른 것이라면 파일을 다른 디렉토리로 옮기고 싶습니다.


1
어떤 종류의 스크립팅 언어를 사용하고 싶은지 알고 있다면 질문에 해당 언어의 이름을 태그하십시오. 도움이 될 것입니다 ...
MatrixFrog

1
아니면 그냥 쉘 스크립트를 작성하려고합니까?
Shalom Craimer 2009

1
“어떤 스크립팅 언어”에 대한 답이 될 것입니다.
bignose 2009

7
어쩌면이 답변과 관련이 없지만 일반적인 팁은 다음과 같습니다. 전체 의심을 한 단어로 설명 할 수있는 경우 (여기서 "인코딩") 그냥하십시오 apropos encoding. 모든 맨 페이지의 제목과 설명을 검색합니다. 내 컴퓨터에서이 작업을 수행 할 때, 나는 그들의 설명에 의해 판단, 나에게 도움이 될 3 도구를 참조하십시오 chardet, chardet3, chardetect3. 그런 다음 man chardet맨 페이지를 읽고 읽으면 chardet그것이 필요한 유틸리티 일뿐입니다.
John Red

1
파일 내용을 변경하면 인코딩이 변경 될 수 있습니다. 예를 들어, vi에서 간단한 c 프로그램을 작성할 때는 아마 us-ascii이지만, 한 줄의 주석을 추가하면이됩니다 utf-8. file파일 내용을 읽고 인코딩하여 인코딩을 알릴 수 있습니다.
Eric Wang

답변:


419

찾고있는 것 같습니다 enca. 인코딩을 추측하고 변환 할 수도 있습니다. 그냥 보는 사람이 페이지 .

또는 실패하면 file -i(linux) 또는 file -I(osx)를 사용하십시오. 파일에 대한 MIME 유형 정보가 출력되며 여기에는 문자 세트 인코딩도 포함됩니다. 나는 그것에 대한 맨 페이지도 발견 했다. :)


1
매뉴얼 페이지에 따르면 ISO 8559 세트에 대해 알고 있습니다. 아마도 조금 덜 커서 읽을 수 있습니다 :-)
bignose

5
Enca는 흥미롭게 들린다. 불행히도 감지는 언어에 따라 크게 달라지며 지원되는 언어 세트는 그리 크지 않습니다. 내 (de)가 없습니다 :-( 어쨌든 멋진 도구입니다.
er4z0r


6
enca영어로 작성된 파일을 분석하는 데 완전히 쓸모없는 것처럼 보이지만 에스토니아어로 무언가를 보는 경우 모든 문제를 해결할 수 있습니다. 매우 유용한 도구입니다 ... </ sarcasm>
cbmanica

6
@vladkras utf-8 파일에 ASCII가 아닌 문자가 없으면 ascii와 구별 할 수 없습니다 :)
vadipp

85
file -bi <file name>

많은 파일에 대해이 작업을 수행하려는 경우

for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done

그러나 파일이 xml 선언에 "encoding = 'iso-8859-1'속성을 가진 xml 파일 인 경우 파일 인코딩은 실제 인코딩이 utf-8 인 경우에도 iso 파일이라고 표시합니다.

6
왜 -b 인수를 사용합니까? file -i *를 수행하면 모든 파일에 대해 추측 된 문자 세트가 출력됩니다.
Hans-Peter Störr 2016 년

4
-b 인수에 대해서도 궁금했습니다. 맨 페이지는 " Do not prepend filenames to output lines
간호

1
파일 출력을 구문 분석 할 필요가없고 file -b --mime-encoding문자셋 인코딩 만 출력합니다.
jesjimher

-b는 'be brief'의 약자이며 기본적으로 방금 지정한 파일 이름을 출력하지 않습니다.
Nikos

36

uchardet -Mozilla에서 포팅 된 인코딩 검출기 라이브러리.

용법:

~> uchardet file.java 
UTF-8

다양한 Linux 배포판 (Debian / Ubuntu, OpenSuse-packman 등)은 바이너리를 제공합니다.


1
감사! 나는 아직 더 많은 패키지에 대해 기뻐하지는 않지만 sudo apt-get install uchardet너무나 쉽게 걱정하지 않기로 결정했습니다.
sage

방금 위의 주석에서 말했듯이 : uchardet은 파일 인코딩이 "windows-1252"라고 잘못 말했지만 파일을 UTF-8로 명시 적으로 저장했습니다. uchardet은 심지어 "신뢰를 가지고 0.4641618497109827"이라고 말하지도 않습니다. 이것은 적어도 당신에게 말도 안되는 말을한다는 것을 암시합니다. 파일, enca 및 encguess가 올바르게 작동했습니다.
Algoman

uchardet는 시작과는 반대로 전체 파일 (20GiB 파일로 시도)을 분석한다는 점에서 file및 의 큰 이점이 enca있습니다.
tuxayo

10

다음은 MacOsX에서 작동하는 파일 -I 및 iconv를 사용하는 예제 스크립트입니다. 질문에 대해서는 iconv 대신 mv를 사용해야합니다.

#!/bin/bash
# 2016-02-08
# check encoding and convert files
for f in *.java
do
  encoding=`file -I $f | cut -f 2 -d";" | cut -f 2 -d=`
  case $encoding in
    iso-8859-1)
    iconv -f iso8859-1 -t utf-8 $f > $f.utf8
    mv $f.utf8 $f
    ;;
  esac
done

6
file -b --mime-encoding문자셋 만 출력하므로 모든 파이프 처리를 피할 수 있습니다.
jesjimher

1
고마워. MacOS에서 지적했듯이 작동하지 않습니다. file -b --mime-encoding 사용법 : file [-bchikLNnprsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] [-M magicfiles ] file ... file -C -m magicfiles 자세한 정보는`file --help '를 시도하십시오.
Wolfgang Fahl

6

그것이 iso-8859-1인지 판단하기는 정말 어렵습니다. iso-8859-1 일 수 있지만 7 비트 문자 만있는 텍스트가있는 경우 알 수 없습니다. 8 비트 문자가있는 경우 상위 영역 문자가 순서대로 인코딩됩니다. 따라서 사전을 사용하여 어떤 단어인지 더 잘 추측하고 어떤 문자인지를 결정해야합니다. 마지막으로 utf-8 일 가능성이 있음을 감지하면 iso-8859-1이 아닌지 확인하십시오.

아무 말도하지 않으면 알 수 없기 때문에 인코딩은 가장 어려운 작업 중 하나입니다.


무력을 행사하는 것이 도움이 될 수 있습니다. 다음 명령은 이름이 WIN 또는 ISO로 시작하는 모든 ecncoding 형식에서 UTF8로 변환하려고 시도합니다. 그런 다음 올바른 인코딩에 대한 힌트를 찾기 위해 출력을 수동으로 확인해야합니다. 물론 ISO 또는 WIN을 대체하여 필터링 된 형식을 변경하거나 grep 명령을 제거하여 필터를 제거 할 수 있습니다. i의 경우 $ (iconv -l | tail -n +2 | grep "(^ ISO \ | ^ WIN)"| sed -e 's / \ / \ ///)); $ i를 반향하십시오; iconv -f $ i -t UTF8 산토스; 끝난;
ndvo

5

데비안에서는 다음을 사용할 수도 있습니다. encguess:

$ encguess test.txt
test.txt  US-ASCII

나는 uchardet우분투에 설치 했고 내 파일은이라고 나에게 말했다 WINDOWS-1252. 테스트를 위해 Kate와 함께 UTF-16으로 저장했기 때문에 이것이 잘못되었다는 것을 알고 있습니다. 그러나 encguess올바르게 추측하면 Ubuntu 19.04에 사전 설치되어 있습니다.
Nagev 2016 년

5

인코딩을 8859에서 ASCII로 변환하려면

iconv -f ISO_8859-1 -t ASCII filename.txt

4

Python에서는 chardet 모듈을 사용할 수 있습니다 : https://github.com/chardet/chardet


존재하지 않는 도메인 : feedparser.org
Rune

이 댓글의, 그것은 Github에서에서 계속 사용할 수 : github.com/dcramer/chardet
릭 Hanlon에 II

이 의견에 따르면, 그것은 github의 chardet / chardet에 있습니다. 답변이 업데이트되었습니다.
Quentin Pradet 2016 년

chardet 보고서 "없음"의에서 파일의 첫 번째 줄에 chardet3 초크 정확한 내 파이썬 스크립트가하는 같은 방법으로.
Joels Elf

3

이것은 당신이 완벽하게 할 수있는 일이 아닙니다. 하나의 가능성은 범위의 모든 문자가 포함되지 않도록 파일에 모든 문자를 조사하는 것 0x00 - 0x1f또는 0x7f -0x9f내가 말했듯이,이 ISO8859의 적어도 하나 개의 다른 변종을 포함하여 파일의 수에 대한 진실 일 수 있지만.

또 다른 가능성은 지원되는 모든 언어로 파일에서 특정 단어를 찾아서 찾을 수 있는지 확인하는 것입니다.

예를 들어, 지원되는 모든 언어 (8859-1)에서 영어 "and", "but", "to", "of"등을 찾아서 파일.

나는 다음과 같은 리터럴 번역에 대해 이야기하지 않습니다.

English   French
-------   ------
of        de, du
and       et
the       le, la, les

가능하지만. 나는 대상 언어로 일반적인 단어에 대해 이야기하고 있습니다. (아이슬란드 어에는 "and"에 대한 단어가 없습니다. "fish"에 대한 단어를 사용해야 할 것입니다. 요점을 설명하는 모든 범죄를 의미합니다]).


2

좀 더 일반적인 답변에 관심이 있다는 것을 알고 있지만 ASCII의 장점은 다른 인코딩에 일반적입니다. 다음은 표준 입력이 ASCII인지 확인하기위한 Python one-liner입니다. (이것은 Python 2에서 작동한다고 확신하지만 Python 3에서만 테스트했습니다.)

python -c 'from sys import exit,stdin;exit()if 128>max(c for l in open(stdin.fileno(),"b") for c in l) else exit("Not ASCII")' < myfile.txt

2

XML 파일 (ISO-8859-1)에 대해 이야기하고 있다면, 그 안의 XML 선언은 인코딩을 지정합니다. <?xml version="1.0" encoding="ISO-8859-1" ?>
따라서 정규 표현식 (예 :)을 사용 perl하여 모든 파일에서 해당 사양을 확인할 수 있습니다 .
자세한 내용은 텍스트 파일 인코딩을 결정하는 방법을 참조하십시오 .


그 줄은 자신이 사용하는 인코딩을 모르는 사람이 복사하여 붙여 넣을 수 있습니다.
Algoman

주의해서, 상단의 선언에 대해서는 파일이 실제로 그렇게 인코딩되어 있음을 보증하지 않습니다. 정말로 인코딩에 관심이 있다면 직접 확인해야합니다.
Jazzepi

2

PHP에서는 다음과 같이 확인할 수 있습니다.

인코딩 목록을 명시 적으로 지정 :

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

보다 정확한 "mb_list_encodings":

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

여기 첫 번째 예에서 일치하는 인코딩 목록 (목록 순서 감지)을 넣었 음을 알 수 있습니다. 보다 정확한 결과를 얻으려면 다음을 통해 가능한 모든 인코딩을 사용할 수 있습니다. mb_list_encodings ()

mb_ * 함수에는 php-mbstring이 필요합니다

apt-get install php-mbstring

0

Cygwin에서는 다음과 같이 작동합니다.

find -type f -name "<FILENAME_GLOB>" | while read <VAR>; do (file -i "$<VAR>"); done

예:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done

iconv가 지원하는 소스 인코딩에서 모든 것을 utf8로 변환하는 awk로 파이프하고 iconv 명령을 작성할 수 있습니다.

예:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done | awk -F[:=] '{print "iconv -f "$3" -t utf8 \""$1"\" > \""$1"_utf8\""}' | bash

0

file 명령을 사용하여 단일 파일의 인코딩을 추출 할 수 있습니다. 다음과 같은 sample.html 파일이 있습니다.

$ file sample.html 

sample.html : 매우 긴 행이있는 HTML 문서, UTF-8 유니 코드 텍스트

$ file -b sample.html

매우 긴 행이있는 HTML 문서, UTF-8 유니 코드 텍스트

$ file -bi sample.html

텍스트 / html; charset = utf-8

$ file -bi sample.html  | awk -F'=' '{print $2 }'

utf-8


1
내가 얻는 결과는 "정규 파일"입니다
Mordechai

0

다음 스크립트를 사용하여

  1. FILTER와 SRC_ENCODING와 일치하는 모든 파일 찾기
  2. 그들의 백업을 만듭니다
  3. DST_ENCODING으로 변환
  4. (선택 사항) 백업 제거

.

#!/bin/bash -xe

SRC_ENCODING="iso-8859-1"
DST_ENCODING="utf-8"
FILTER="*.java"

echo "Find all files that match the encoding $SRC_ENCODING and filter $FILTER"
FOUND_FILES=$(find . -iname "$FILTER" -exec file -i {} \; | grep "$SRC_ENCODING" | grep -Eo '^.*\.java')

for FILE in $FOUND_FILES ; do
    ORIGINAL_FILE="$FILE.$SRC_ENCODING.bkp"
    echo "Backup original file to $ORIGINAL_FILE"
    mv "$FILE" "$ORIGINAL_FILE"

    echo "converting $FILE from $SRC_ENCODING to $DST_ENCODING"
    iconv -f "$SRC_ENCODING" -t "$DST_ENCODING" "$ORIGINAL_FILE" -o "$FILE"
done

echo "Deleting backups"
find . -iname "*.$SRC_ENCODING.bkp" -exec rm {} \;

0

이 명령으로 :

for f in `find .`; do echo `file -i "$f"`; done

디렉토리 및 하위 디렉토리의 모든 파일과 해당 인코딩을 나열 할 수 있습니다.


-2

Perl에서는 Encode :: Detect를 사용하십시오.


7
쉘에서 사용하는 방법을 예를 들어 줄 수 있습니까?
Lri

다른 포스터 (@fccoelho)는 Python 모듈을 +3을 얻는 솔루션으로 제공 했으며이 포스터는 Perl 모듈을 제외하고는 매우 유사한 답변에 대해 -2를 얻습니다. 왜 이중 표준인가?!
Happy Green Kid Naps

4
아마도 펄 원 라이너의 코드 예제 가이 대답에 도움이 될 것입니다.
vikingsteve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.