2010年10月5日火曜日

AWKでバイナリ入力する方法(Gawk専用) - AWK

AWKの入出力とコマンド実行機能
完全なバイナリ入力は、Gawkで対応していました。
但し、強い癖がありますから、バイナリ出力よりも扱いは難しいです。

o 入力を特定の長さで区切る事が出来ません。
o 変数RSで指定した行区切り文字が出現しない場合、ファイルを全部メモリに読み込みます。


**** 原理
o 変数 BINMODEを使います。これによって、Windowsにおける改行コードの自動変換機能を無効にします。
o 同時に、AWKの言語設定を強制的に変更します。
   + 理由は、文字をバイト単位で切り出す時に、AWK処理系が日本語の全角文字に対応しようとして、文字化けを起こすからです。
o なお、mawkの場合は、バイナリコードの入力に対応していません。
   + 文字コードの 0(0x00)を読み込む事が出来ませんでした。


**** 手順
** 「-Wctype=ASCII」オプションを付ける方法(Gawk on Windows専用)
o この方法は、Gawk on Windows 3.1.7のみ使用する事が出来ます。

o Gawkを起動する時の、コマンドラインオプションを指定します。
--------
gawk -Wctype=ASCII -v BINMODE=3 a.awk in.txt > out.txt
--------

   + BINMODE=3は、読み書き両方でバイナリモード
   + BINMODE=1は、読み込みのみバイナリモードです。


** Windowsの言語設定を「英語(米国)」などにする方法(Gawk専用)
o この方法は、Gawk on Windows 3.1.7 / Gawk for Windows 3.1.6の両方で使用する事が出来ます。

o 最初に、Windowsのコントロールパネルで、標準で1バイトしか使わない言語を選択します。
   + Windows XPの場合は、スタートボタンから[コントロールパネル]-[地域と言語のオプション]
   + 出てくる画面の「地域オプション」タブで、「英語(米国)」を選んで、「適用」ボタンもしくは「OK」ボタン。
o 設定出来たら、Gawkの起動オプションで、変数BINMODEを設定します。
--------
gawk -v BINMODE=3 a.awk in.txt > out.txt
--------

   + BINMODE=3は、読み書き両方でバイナリモード
   + BINMODE=1は、読み込みのみバイナリモードです。


**** メモ
o AWKには、「行の区切り文字が不特定の時に、上手にファイルを扱う事が出来ない」という欠点があります。
   + AWK処理系は、変数RSで指定した文字が出てくるまでの間、読み込みを続けます。
   + そして、「RS = ""」とすると、読み込まないのではなく、ファイルの最後までを1行とみなします。
   + また、「RS = "[.]"」(任意の一文字で区切る)の書き方を、AWKはサポートしていません。
      + このように書くと、ビリオドが出てきた所で区切ります。
o 実際にGawkでバイナリファイルを扱う時は、事前に強制的に区切り文字を入れるようにすると、読み込み時にメモリー使用量が少なくて済みそうです。
   + その部分は、PerlやC言語などを使って書く必要があります。


**** 確認した処理系
o Gawk on Windows 3.1.7
o Gawk for Windows 3.1.6 -- Windowsの言語設定の変更が必要
o mawk MBCS (32bit版) 1.3.3 -- 非対応
o Mawk for Windows 1.3.3 -- 非対応
o original = the one true awk(updated May 1, 2007) -- 非対応


==
関連ページ:
    ▼AWKの入出力関数とコマンド実行機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > 改行コード。Windows / UNIX / Mac の違いについて
    GawkでUTF-8のファイルを読み込む時の注意点
    Gawkで、UTF-8のファイルからBOMを除去する
    +
    AWKでバイナリ出力する方法(mawk, Gawk専用)
    BINMODE = バイナリモードで読み書きする(mawk,Gawk専用)
    RS = 1行読み込む時の改行文字