スクリプトを使用してUnixでファイルのエンコーディングを見つける方法

StackOverflow https://stackoverflow.com/questions/805418

  •  03-07-2019
  •  | 
  •  

質問

ディレクトリに配置されているすべてのファイルのエンコーディングを見つける必要があります。使用されているエンコーディングを見つける方法はありますか?

fileコマンドではこれができません。

私にとって興味深いエンコーディングは、ISO-8859-1です。エンコーディングがそれ以外の場合、ファイルを別のディレクトリに移動します。

役に立ちましたか?

解決

encaを探しているように聞こえます。推測し、エンコード間で変換することもできます。 manページをご覧ください。

または、失敗した場合は、file -i(linux)またはfile -I(osx)を使用します。これにより、ファイルのMIMEタイプ情報が出力されます。これには、文字セットエンコーディングも含まれます。 manページも見つけました:)

他のヒント

file -bi <file name>

多数のファイルに対してこれを行う場合

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

uchardet -Mozillaから移植されたエンコーディング検出ライブラリ。

使用法:

~> uchardet file.java 
UTF-8

さまざまなLinuxディストリビューション(Debian / Ubuntu、OpenSuse-packmanなど)がバイナリを提供しています。

これは、ファイル-Iおよびiconvを使用してMacOsXで動作するスクリプトの例です 質問には、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

iso-8859-1かどうかを判断するのは非常に困難です。 iso-8859-1である可能性のある7ビット文字のみのテキストがある場合、それはわかりません。 8ビット文字を使用している場合、上位領域の文字も順番にエンコードされています。そのため、辞書を使用して、どの単語であるかをより正確に推測し、そこからどの文字であるかを判断する必要があります。最後に、utf-8である可能性があることを検出した場合、iso-8859-1ではないことを確認します

エンコーディングは、何も伝えていないかわからないため、最も難しいことの1つです

Pythonでは、chardetモジュールを使用できます。 https://github.com/chardet/chardet

Debianでは以下も使用できます:encguess

$ encguess test.txt
test.txt  US-ASCII

これは、絶対確実にできる方法ではありません。 1つの可能性は、ファイル内のすべての文字を調べて、0x00 - 0x1fまたは0x7f -0x9fの範囲の文字が含まれていないことを確認することですが、前述したように、これは少なくともISO8859のもう1つのバリアント。

別の可能性は、サポートされているすべての言語でファイル内の特定の単語を探し、それらを見つけることができるかどうかを確認することです。

したがって、たとえば、英語の<!> quot; and <!> quot;、<!> quot; but <!> quot;、<!> quot; to <!> quot ;、 <!> quot; of <!> quot; 8859-1のサポートされているすべての言語で同様に実行し、ファイル内に多数の出現があるかどうかを確認します。

次のような文字通りの翻訳については話していない:

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

それは可能ですが。ターゲット言語の一般的な単語について話している(私が知っている限り、アイスランド語には<!> quot; and <!> quot;の単語はありません-<!> quot; fishの単語を使用する必要があります<!> quot; [ちょっとステレオタイプなのはごめん、私は攻撃を意味するものではなく、ポイントを示すだけです])

XMLファイル(ISO-8859-1)について話している場合、その内部のXML宣言はエンコードを指定します:<?xml version="1.0" encoding="ISO-8859-1" ?>
そのため、正規表現(たとえばperlを使用)を使用して、そのような仕様のすべてのファイルをチェックできます。
詳細については、テキストファイルのエンコーディングを決定する方法

エンコーディングを8859からASCIIに変換するには:

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

より一般的な答えに興味があることは承知していますが、ASCIIの長所は通常、他のエンコーディングにも有効です。以下は、標準入力がASCIIかどうかを判断するためのPythonワンライナーです。 (これは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

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

それをawkにパイプして、iconvでサポートされているソースエンコーディングからすべてをutf8に変換する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

fileコマンドを使用して、単一ファイルのエンコーディングを抽出できます。 sample.htmlファイルには次のものがあります。

$ file sample.html 

sample.html:HTMLドキュメント、UTF-8 Unicodeテキスト、非常に長い行

$ file -b sample.html

HTMLドキュメント、UTF-8 Unicodeテキスト、非常に長い行

$ file -bi sample.html

text / html; charset = utf-8

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

utf-8

次のスクリプトを使用して

  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 {} \;

Perlでは、Encode :: Detectを使用します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top