it-swarm-ja.tech

ファイルシェルスクリプトのエンコーディング

シェルスクリプトでファイルのエンコードを確認するにはどうすればよいですか?ファイルがutf-8またはiso-8859-1でエンコードされているかどうかを知る必要があります。

ありがとう

33
rizidoro

私はただ使うだろう

file -bi myfile.txt

特定のファイルの文字エンコーディングを決定します。

外部依存関係を備えたソリューションですが、fileは最近ではすべての半現代のディストリビューションの間で非常に一般的であると思われます。

編集:

Laurence Gonsalvesのコメントへの応答として:bは 'brief'(ファイル名を含まない)にするオプションであり、i--mimeしたがって、最も移植性の高い方法(Mac OSXを含む)は、おそらく次のとおりです。

file --mime myfile.txt 
58
ChristopheD

100%確実にする方法はありません(エンコードを内部的に記述しているファイル形式を扱っている場合を除く)。

この区別をしようとするほとんどのツールは、ファイルをutf-8(より厳密なエンコーディング)としてデコードしようとし、失敗した場合はiso-8859-1にフォールバックします。これは、iconvを「手作業で」行うか、fileを使用して実行できます。

$ file utf8.txt
utf8.txt: UTF-8 Unicode text
$ file latin1.txt
latin1.txt: ISO-8859 text

ASCIIファイルはUTF-8とISO-8859-1の両方に対応しています。

$ file ascii.txt
ascii.txt: ASCII text

最後に、たとえば、自然言語であると仮定して統計的手法を使用しない限り、ISO-8859-1とISO-8859-2を区別する実際の方法はありません。これがおそらくファイルが「ISO-8859」と言う理由です。

9

ファイルコマンドfile --mime myfile.textを使用できます

8
jochil

ファイルコマンドは100%確実ではありません。簡単なテスト:

#!/bin/bash

echo "a" > /tmp/foo

for i in {1..1000000}
do
  echo "asdas" >> /tmp/foo
done

echo "üöäÄÜÖß " >> /tmp/foo

file -b --mime-encoding /tmp/foo

この出力:

us-ascii

アスキーはドイツのウムラウトを知りません。

ファイルは一連のバイト(バイトのシーケンス)です。メタデータ(BOMはutf-16およびutf-32、MIME、データのヘッダーにのみ推奨)を信頼しなければ、エンコードを実際に検出することはできません。バイトのシーケンスは、utf-8、ISO-8859-1/2、または必要なものとして解釈できます。さて、iso-8850-1/utf-8マップが存在するかどうかは、特定のシーケンスに依存します。必要なのは、ファイルコンテンツ全体を目的の文字エンコードにエンコードすることです。失敗した場合、目的のエンコーディングには、このバイトシーケンスのマップがありません。

シェルでは、Python、Perl、またはLaurence Gonsalvesのようなiconvを使用します。 python this:で使用するテキストファイルの場合:

f = codecs.open(path, encoding='utf-8', errors='strict')


def valid_string(str):
  try:
    str.decode('utf-8')
    return True
  except UnicodeDecodeError:
    return False

ファイルがテキストファイルであることをどうやって確認しますか。あなたはしません。目的の文字エンコーディングで行ごとにエンコードします。 OK、少し信頼を追加して、BOMが存在するかどうかを確認できます(ファイルはutfエンコードされています)。

4
broadband