iconv は BOM 付き UTF-16 を生成します

iconv は BOM 付き UTF-16 を生成します

に触発されたこの質問iconvコマンドを使用して、BOM と指定されたエンディアンを持つ UTF-16 出力を生成できますか?

このiconvコマンドは、テキストをあるエンコーディングから別のエンコーディングに変換します。

例えば:

echo hello | iconv -f ascii -t utf-16

の UTF-16 表現を生成します"hello\n"

UTF-16 ファイルは、常にではありませんが、多くの場合、バイト オーダー マーク (BOM) で始まります。これは、Unicode 文字 の 2 バイト エンコードです。最初の 2 バイトがまたは でU+FEFFあるかどうかを確認することで、BOM 付きの UTF-16 ファイルのエンディアンを判断できます。FE FFFF FE

このiconvコマンドには、UTF-16 出力を生成するためのいくつかのオプションがあります。

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

このコマンド:

echo hello | iconv -f ascii -t utf-16be

ビッグエンディアンのUTF-16を生成するBOMなし; エンディアンを指定した場合、出力でそれを示す必要がないと想定しているようです。同様に、utf-16leBOM なしのリトルエンディアンの UTF-16 を生成します。

これ:

echo hello | iconv -f ascii -t utf-16

(私のx86 Ubuntuシステムでは) リトルエンディアンUTF-16を生成しますBOM ですが、リトルエンディアン システムでも、同様のコマンドで BOM 付きのビッグエンディアン UTF-16 が生成されるという報告を見たことがあります。

utf-16beまたはを使用しutf-16leて BOM を手動で先頭に追加することもできますが、iconvコマンドだけを使用するソリューションを探しています。

別の回避策として、もしエンディアンネスが何を生成するかはご存知でしょう-t utf-16:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

私がのように使用方法は次のとおりです。

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

しかし、iconvそれをサポートしていません。

編集 :

x86 Mac OSX システムにアクセスできる方は、次のコマンドの (コピー アンド ペーストされた) 出力を示すコメントを投稿していただけますか?

echo hello | iconv -f ascii -t utf-16 | od -x

答え1

いいえバイト順序を指定すると、iconvBOM は挿入されません。

これはユニコードコンソーシアム

Q: BOM をどのように扱えばよいですか?

A: 従うべきガイドラインは次のとおりです。

  1. 特定のプロトコル (.txt ファイルに対する Microsoft 規則など) では、ファイルなどの特定の Unicode データ ストリームで BOM の使用が必要になる場合があります。このようなプロトコルに準拠する必要がある場合は、BOM を使用します。
  2. 一部のプロトコルでは、タグなしテキストの場合にオプションのBOMが許可されます。その場合、
    • テキスト データ ストリームがプレーン テキストであることがわかっていても、エンコードが不明な場合は、BOM を署名として使用できます。BOM がない場合、エンコードは何でもかまいません。
    • テキスト データ ストリームがプレーンな Unicode テキストであることがわかっている場合 (ただし、どのエンディアンであるかは不明)、BOM を署名として使用できます。BOM がない場合、テキストはビッグ エンディアンとして解釈されます。
  3. 一部のバイト指向プロトコルでは、ファイルの先頭に ASCII 文字が必要です。これらのプロトコルで UTF-8 を使用する場合は、エンコード形式の署名として BOM を使用することは避けてください。
  4. データストリームの正確なタイプがわかっている場合(例:UnicodeビッグエンディアンまたはUnicodeリトルエンディアン)、BOMは使用しないでください。特に、 データストリームがUTF-16BE、UTF-16LE、UTF-32BEと宣言されている場合 またはUTF-32LE BOMしてはならない利用される。

(強調は筆者)

iconvこれらのガイドラインの最後の部分に忠実であろうとしていると思います。


アップデート。

余談

私の意見では:

  1. BOM を指定するオプションは、iconv にとって確かに便利な追加機能となるでしょう。

  2. BOMのないUTF-16LEファイルWindows でも使用できますが、場合によっては追加の作業が必要になります。たとえば、メモ帳のファイルを開くダイアログでは、「UTF-16LE」の Microsoft 名である「Unicode」を選択できますが、これは (当然のことながら) BOM のないファイルでも機能するようです。

  3. Windows メモ帳 (XP) では、エクスプローラーでファイル名をダブルクリックするなど、通常の方法で UTF-16LE テスト ファイル (BOM なし) または UTF-8 テスト ファイル (BOM なし) を開くことができます。これは使えるように思えます。Windows がエンコードを誤って推測することがあるのは承知しています。その場合は、ファイルを開くときにメモ帳にエンコードを指示する必要があります。この不便さから​​、Windows で使用するテキスト ファイルには BOM を含めることが望ましいと言えます。

  4. 特定のアプリケーションが BOM 付きの UTF-16LE ファイル以外では動作しない場合は、BOM なしの UTF-16LE ファイルもその特定のアプリケーションでは使用できないことに同意します。

  5. 私はそう思うもしすべてを UTF-8 (BOM なし) で動作させることができます。これは長期的には最善の解決策です。

しかし、質問に対する答えは「iconv コマンドを使用して、BOM と指定されたエンディアンを持つ UTF-16 出力を生成できますか?" 現在 "いいえ「」。

答え2

BOM をファイルに追加する場合は、手動で追加できます。

UTF-8 BOM(EF BB BF)の場合

file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"

UTF-16BE BOM(FE FF)の場合

file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"

UTF-16LE BOM(FF FE)の場合

file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"

注記:

おそらく、それぞれのケースのBOMが異なることにお気づきでしょう。詳細はこちら:

関連情報