2010年9月15日水曜日

AWKプログラムの中で、8進数や16進数を使う方法 - AWK

AWKの数値計算関数と関連機能
8進数や 16進数が大好きな方向けの情報です。

o 最低限の機能しかありませんので、不足している機能は自作します。
  + 実数を16進数表現する機能はありません。
  + 文字から文字コード(= 数値)に変換する機能もありません。


**** 手順
o 整数の値を16進数や8進数で書く方法(Gawk専用)
o 整数を16進数や8進数で表示する方法
o 16進数文字列を数値に変換する方法(Gawk専用)
o 文字列を文字コードで書く方法(= 注意事項あり)
o 文字1つを文字コードで書く方法(= 注意事項あり)


** 整数の値を16進数や8進数で書く方法(Gawk専用)
--------
v = 393; # 10進数表現

# Gawkの拡張機能
v = 0x189; # 393の 16進数表記
v = 0611; # 393の 8進数表記
--------



** 整数を16進数や8進数で表示する方法
--------
printf("%x\n", 393); # 16進数で表示
printf("%o\n", 393); # 8進数で表示
--------

o AからFを大文字にしたい時は、"%X"
o 16進数の場合、0x や 0Xを付けたい時は、"%#x" や "%#X"
o 8進数の場合、0 を付けたい時は "%#o"
o 文字にしたいだけの時は、printfの代わりに sprintfを使います。


** 16進数文字列を数値に変換する方法(Gawk専用)
o strtonum 関数を使います。
--------
v = "393" + 0; # 強制的に数値にしたい時、0と足し算します。

# Gawkの拡張機能
v = strtonum("0x189"); # 16進数表記を数値に変換
v = strtonum("0661"); # 8進数表記を数値に変換
--------

o 16進数表記の「0x」は、「0X」と書く事も出来ます。


** 文字列を文字コードで書く方法(= 注意事項あり)
o 16進数の場合「\x12」、8進数の場合「\123」の形で書きます。
o 2文字や3文字に満たない時は、数字の左を0で埋めます。
--------
v = "MikuSan";
v = "\x4d\x69\x6b\x75\x53\x61\x6e"; # 16進数表記
v = "\115\151\153\165\123\141\156"; # 8進数表記

v = "\t"; # タブ文字の場合
v = "\x09" # 16進数表記では、前ゼロを付けます。
v = "\011"; # 8進数表記でも、前ゼロを付けます。
--------

o この方法については、処理系によって制約がありますので、個別対応します。
o Gawkの場合(Gawk on Windows 3.1.7 / Gawk for Windows 3.1.6)
   + これらの処理系では、16進表記させた後に16進数となる文字が続くと、予想と異なる結果になります。
   + (例。"\x23a" は「#a」を期待して書くのですが、mawk以外では「:」コロン = 0x3a になりました。)
   + ですので、問題が起こる時は、16進数表記だけを変換して、変換結果を文字列として並べます。
o mawkの場合(mawk MBCS (32bit版) 1.3.3 / Mawk for Windows 1.3.3)
   + これらの処理系では、文字コードの 0 (= \x00)を入れると、強制終了もしくは異常終了します。
   + \x00 は、通常、目に見える文字ではありませんが、一部の文字コード(UTF-16)では、目に見える文字(= 2バイト以上あります)の一部として使用されています。
o original = the one true awk(updated May 1, 2007)の場合
   + Gawk と mawk の両方の問題を抱えています。


** 文字1つを文字コードで書く方法(= 注意事項あり)
--------
# 変数に入れる方法
v = sprintf("%c%c%c%c%c%c%c", 77,105,107,117, 83, 97,110); # 結果は MikuSan
v = sprintf("%c%c%c%c%c%c%c", 0x4d, 0x69, 0x6b, 0x75, 0x53, 0x61, 0x6e); # Gawk限定。結果は MikuSan

# 直接書き出す方法
printf("%c%c%c%c%c%c%c", 77,105,107,117, 83, 97,110); # 結果は MikuSan
--------

o 画面やファイルに書き出す時、改行コード 0x0aは、0x0d0a に自動変換されます。
   + mawkやGawkでは、変数 BINMODEを使って、この自動変換を無くす事が出来ます。
o 文字コード の 0(0x00)を文字列中に含める事が出来るのは、Gawkのみです。
   + mawkとオリジナルは、このコードを文字列変数の中に入れる事は出来ません。


==
関連ページ:
    ▼AWKの数値計算関数と関連機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > int = 実数や文字列を整数化する
    strtonum = 10進数、8進数、16進数の文字列を数値に変換する(Gawk専用)
    sqrt = 平方根を求める
    +
    AWKでバイナリ出力する方法(mawk, Gawk専用)
(2010年9月23日追加。文字1つを文字コードで書く方法)
(2010年9月16日追加。文字列を文字コードで書く時の、mawkの制限)