2010年9月7日火曜日

文字列から文字を1つずつ取り出す方法 - AWK

AWKの文字列操作関数と関連機能
AWKの文字列は、C言語とは異なり、配列の形で直接取り出す事は出来ません。
その代わり、処理系によっては、バイトを意識せずに文字を取り出す事が出来ます。

o 文字を1つずつ取り出す方法 -- substr関数を使います。
o 配列に入れてしまう方法 -- split関数を使います。


**** 手順
** 方法1. 文字を1つずつ取り出す方法
o substr関数を使います。
--------
BEGIN {
  v = "ミクさん";
  print "文字列「" v "」の文字分け結果";
  for (i = 1; i <= length(v); ++i) {
    print i " : " substr(v, i, 1); # 文字を1つずつ取り出します。
  }
}
--------

o 実行結果
--------
文字列「ミクさん」の文字分け結果
1 : ミ
2 : ク
3 : さ
4 : ん
--------

o Gawk以外で漢字などの全角文字を扱う時は、1バイトずつ取り出しますので、注意が必要です。
o 性能を気にするような使い方をする場合、length(v)の計算を for文の外に出すと、少し速くなりそうです。


** 方法2。配列に入れてしまう方法
o split関数を使います。
--------
BEGIN {
  v = "ミクさん";
  print "文字列「" v "」の文字分け結果";
  n = split(v, a, ""); # 区切り文字に、空文字を指定するのが、ポイントです。
  for (i = 1; i <= n; ++i) {
    print i " : " a[i];
  }
}
--------

o 実行結果
--------
文字列「ミクさん」の文字分け結果
1 : ミ
2 : ク
3 : さ
4 : ん
--------

o 「Gawkとmawk32」以外で漢字などの全角文字を扱う時は、1バイトずつ取り出しますので、注意が必要です。


==
関連ページ:
    ▼AWKの文字列操作関数と関連機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > 文字列中で使用出来る特殊文字
    ツール。文字列からアスキーコードを調べます(String to ASCII)
    length = 文字列や配列の長さを調べる
    +
    substr = 文字列の一部を取り出す
    split = 文字列を分割する
    文字列を組み立てる

default = switch文の中で、全ての選択肢と一致しない時に実行する(Gawk専用) - AWK

AWKのパターンと制御文
○Gawk on Windows △(注記あり)Gawk ×mawk32 ×Mawk ×awk
switch文の中で指定します。
switchで指定した値が caseを使って書いた全ての選択肢と一致しなかった時、この位置以降に登場する文を実行します。

**** 書式
--------
default: [ 実行する文 ]
--------

o 以下、「switch」の説明をご覧下さい


**** メモ
o Gawk for Windows 3.1.6では、「実行する文」の中に break を含める事が出来ません。
o この場合、default句を全ての case句よりも下に書くようにすると、break を書かなくて済みます。


**** 確認した処理系
o Gawk on Windows 3.1.7
o Gawk for Windows 3.1.6 -- default句で break不可
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
    ▼制作メモ
    > while = 条件付きで繰り返す
    do = 後でwhile判定する繰り返し
    for = 繰り返し文その2
    +
    switch = 選択肢を選んで実行する(Gawk専用)

case = switch文の中で、選択肢を指定する(Gawk専用) - AWK

AWKのパターンと制御文
○Gawk on Windows ○Gawk ×mawk32 ×Mawk ×awk
switch文の中で指定します。
switchで指定した値が 選択肢と一致した時、選択肢以降に登場する文を実行します。

**** 書式
--------
case 選択肢: [ 実行する文 ]
--------

o 以下、「switch」の説明をご覧下さい


**** 確認した処理系
o Gawk on Windows 3.1.7
o Gawk for Windows 3.1.6
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
    ▼制作メモ
    > default = switch文の中で、全ての選択肢と一致しない時に実行する
    while = 条件付きで繰り返す
    do = 後でwhile判定する繰り返し
    +
    switch = 選択肢を選んで実行する(Gawk専用)

BINMODE = バイナリモードで読み書きする(mawk,Gawk専用) - AWK

AWKの入出力関数とコマンド実行機能
○Gawk on Windows ○Gawk △(書き出しのみ)mawk32 ○Mawk ×awk
オリジナルのAWK以外は、テキストファイル以外を読み書きする事も出来ます。

o 書き出しについては、コマンドで BINMODEを指定する方法にしないと、切り替わらないみたいです。
o 但し、mawk(とオリジナル)には、文字コード 0x00 を扱う事が出来ないという制限があります。

**** 書式
--------
BINMODE = モード
--------

o BINMODEは変数です。
o モード -- バイナリモードでファイルを開く事が出来ます。
   + 0 もしくは、空文字("") = 何もしません。テキストモードのままです。(初期値)
   + 1 = 読み込みのみ、バイナリモード
   + 2 = 書き出しのみ、バイナリモード
   + 3 = 読み込みと書き出しの両方で、バイナリモード

o Gawk on Windowsの場合は、文字で指定する事も出来ます。
   + r = 読み込みのみ、バイナリモード
   + w = 書き出しのみ、バイナリモード
   + その他の文字 = 読み込みと書き出しの両方で、バイナリモード

o 処理系によっては対応していない値があります。詳しくは、下の機能欄をご覧下さい。


**** 使用例(Gawk on Windowsの場合)
** 変数 BINMODE の設定例
o ファイルを読み込み前に書く方法
--------
BEGIN {
  BINMODE=1;
}
--------


o 実行コマンドの一部として書く方法(= 2や3にする時は、この方法で指定します)
--------
gawk -v BINMODE=1 -f a.awk in.txt > out.txt
--------


** 使用しているモードの確認方法
o 読み込みで使用しているモードの確認方法
--------
BEGIN {
  print "BINMODE = " BINMODE "\r";
}
{
  mode = (substr($0, length($0), 1) == "\r")? ("バイナリ"):("テキスト");
  print "読み込みは、" mode "モード\r";
  exit;
}
--------

o バイナリモードへの切り替えに成功すると、Windowsの改行コード \r\nの \rが、行末に現れます。
o 行末に"\r"を追加している理由は、書き出しがバイナリモードの時にも改行させたいからです。

o 書き出しで使用しているモードの確認方法
--------
BEGIN {
  print "BINMODE = " BINMODE;
  print "です。";
  print "メモ帳で開いた時に、BINMODE以降が1行で表示されたら、バイナリモード。";
  print "(Windows XPで確認しました)";
}
--------

o こちらは、ファイルの改行コードが\nだけの時、メモ帳で開くと改行されない事を利用しています。


**** 機能
o この変数を使うと、ファイルの読み書き時、バイナリモードに設定する事が出来ます。
o 目的のファイルを開く前に指定する必要があります。
   + 書き出しについては、コマンドで BINMODEを指定する方法にしないと、切り替わらないみたいです。
o 詳細は、書式説明の通りです。
o この機能をサポートしていない処理系があります。

** テキストモードとバイナリモードの違いについて
o バイナリモード = ファイルを読み書きする時、改行コードを自動変換しません。
o テキストモード = "\n"とWindowsファイルの改行コード "\r\n"を自動変換します。
   + ファイルの改行コードは、システムによって異なります。
   + 例えば、UNIX標準の改行コードは、"\n"。
   + ですので、同じAWKでも、Windows版とUNIX版では、改行コードの扱いが異なります。
o 通常は、テキストモードの方が便利です。困った時に切り替えます。

** 処理系に依存する動作
o 表の通りです。
o 但し、mawk(とオリジナル)には、文字コード 0x00 を扱う事が出来ないという制限があります。
o バイナリデータの完全な読み書きについては、実用上、他の手順や知識も必要になります。
    + 「AWKでバイナリ出力する方法」(mawk, Gawk専用)
    + 「AWKでバイナリ入力する方法」(Gawk専用)

バイナリモードになる条件
BINMODE
の値
Gawk on
Windows
3.1.7
Gawk for
Windows
3.1.6
mawk32
1.3.3
Mawk for
Windows
1.3.3
awk
(May 1,
2007)
説明
 R = 読み込み / W = 書き出し 
0×××××何もしません。テキストモード
(空文字)×××××何もしません。テキストモード
1RR×R×読み込みをバイナリモード
rR××××読み込みをバイナリモード
2WWWW×書き出しをバイナリモード
wW××××書き出しをバイナリモード
3RWRWWRW×両方をバイナリモード
rwRW××××両方をバイナリモード
wrRW××××両方をバイナリモード
RRW××××両方をバイナリモード
WRW××××両方をバイナリモード
o UNIX版では、この機能をサポートしていない事があります。
   + モードを切り替えても、改行文字は同じだからです。
   + 少なくとも、mawk 1.3.3の場合は、Windows版(とMS-DOS版)のみが対応していました。


**** 確認した処理系
o Gawk on Windows 3.1.7 -- 文字でも指定可能
o Gawk for Windows 3.1.6
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
    ▼制作メモ
    > /inet = AWKからインターネットにアクセスする
    /dev/stdout = 標準出力を示すファイル名
    /dev/stderr = 標準エラー出力を示すファイル名
    +
    AWKでバイナリ出力する方法(mawk, Gawk専用)
    AWKでバイナリ入力する方法(Gawk専用)
    AWKプログラムの中で、8進数や16進数を使う方法
    getline = ファイル(やパイプ)から1行読み込む
    printf = 文字列を組み立ててファイルなどに書き出す
    print = ファイルなどに書き出す
(2011年7月29日訂正。使用例のコマンド記述は -f awkファイル名)
(2010年10月5日変更。メモ欄の記述を、処理系に依存する動作欄に統合)
(2010年9月7日変更。15時頃と17時頃に自動公開したのは作成中のもの。書き直したものを改めて公開)