2010年6月10日木曜日

$0 = 最後に読み込んだデータ、1行分 - AWK

AWKの文字列操作関数と関連機能
AWKの入出力関数とコマンド実行機能
○Gawk on Windows ○Gawk ○mawk32 ○Mawk ○awk
最後に読み込んだデータ、1行分です。

o 入出力や $0 の直接操作の他に、文字列操作関数が暗黙で使う場合があります。(gsub, sub, gensub


**** 書式
--------
$0
もしくは
$0 = 設定したい値
--------

o $0は変数です。値を代入する事も出来ます。
o 設定したい値 -- 文字列です。配列を指定する事は出来ません。
   + 数値を指定すると、文字列に変換されます。
   + この時の変換規則は、"%.6g"固定みたいです。(変数 CONVFMTOFMTの値は、参照しません。)
   + 内部的には数値としての値も持っていますが、文字列として表示されます。


**** 使用例
--------
{
  print $0; # 現在の入力データ。1行分が入っています。
}
END {
  print $0; # 最後に入力したデータが、残っています。
}
--------

o 行末のセミコロンは、C言語の書き方に合わせました。無くても動きます。


**** 機能
o 最後に読み込んだデータ、1行分が入っています。
o 改行文字は入っていません。
   + 改行文字は変更する事が出来ます。変数 RSを使います。
o この変数に値を代入すると、変数 $1、$2などや、変数 NFにも自動反映されます。
   + 代入した値は、列に分割されて、変数 $1などに自動反映されます。列の区切り文字には、変数 FSを使います。
   + また、変数 NFには、$1などに分割した数が入ります。
o 次の操作は、$0の値を変更します。
   + getlineを、引数無しで呼び出した時
   + gsub, sub, gensubを、対象文字列の指定無しで(もしくは$0を指定して)呼び出した時
   + $1など変数「$ + 数字」に値を代入した時
      + この時、各列の間にある区切り文字を、OFSの値で置き換えます。
      + $1 = $1のように同じ値を代入しても、同じ動きをします。
   + $0の値を直接上書きした時
   + 変数 NFに値を代入した時の動作は、処理系によって異なります。

** 処理系に依存するかもしれない動作
o UTF-8のファイルを読み込む時、1行目の$0と$1に、UNICODE特有の見えない文字(BOM)が入っている事があります。
   + この場合、見えない文字の入った値を1行目の先頭以外で書き出すと、文字化けします。
   + (例。Windows XP (SP3)のメモ帳で作成し、文字コード UTF-8で保存した時)
   + 対策方法は「UTF-8のファイルから、BOMを除去する方法

** 処理系に依存する動作
o 変数 NFに値を代入した時、$0の値を自動変更(= 再構築)する処理系
   + Gawk on Windows 3.1.7
   + Gawk for Windows 3.1.6
   + mawk MBCS (32bit版) 1.3.3
   + Mawk for Windows 1.3.3
   + この時、各列の間にある区切り文字を、変数OFSの値で置き換えます。
   + NF = NFのように同じ値を代入しても、同じ動きをします。
   + これらの処理系では、NFを負の値にすると、強制終了します。
o 変数 NFに値を代入した時、$0の値を変更しない処理系
   + original = the one true awk(updated May 1, 2007)
   + この処理系では、NFの値が負になっても、$0の値を参照する事が出来ます。


**** メモ
o $0 に実数を入れた時、CONVFMTの値が効きませんが、判定は○にしました。
o 理由は、AWKの仕様上、$0に実数を1つだけ入れるような使い方は、考え難いからです。


**** 確認した処理系
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順
    ▼制作メモ
    > RSTART = match関数で見つけた文字列の先頭位置
    RLENGTH = match関数で見つけた文字列の長さ
    > $1 = 最後に読み込んだデータの1列目
    NF = 最後に読み込んだ行の列数
    +
    ファイルからデータを読み込む
    NR = これまでに読み込んだ行数
    FNR = 現在読み込み中のファイルから読み込んだ行数
(2011年2月13日追加。gensubも暗黙使用)
(2010年9月9日追加。変数NFに代入した時の影響)
(2010年9月3日追加。実数を代入した時の動作)

match = 正規表現の登場位置を調べる - AWK

AWKの文字列操作関数と関連機能
○(文字数)Gawk on Windows ○(文字数)Gawk ○(バイト数)mawk32 ○(全角不可)Mawk ○(全角不可)awk
文字列の登場位置を調べます。正規表現を使用出来ます。

o Gawkでは、3つ目の引数を指定する事が出来ます。


**** 書式
--------
match( 検索対象文字列, 検索条件 )
Gawkの場合は
match( 検索対象文字列, 検索条件 [, 検索結果詳細] )
--------

o 検索対象文字列
o 検索条件 -- 正規表現で指定します。
   + 文字列で指定する事も出来ました。
o 検索結果詳細 -- Gawkの拡張です。配列を返します。
   + 詳細は下の通りです。呼び出す時に、値を設定する必要はありません。
o 戻り値 -- キーワードが見つかった位置(先頭は1)。
   + 文字を数える時の単位は、処理系によって異なります。詳細は、下の通りです。
   + 見つからない時は 0を返します。

o この機能を呼び出すと、次の2つの変数に値が入ります。
   + 変数 RSTART -- キーワードが見つかった位置(先頭は1)。見つからない時は 0が入ります。
   + 変数 RLENGTH -- 見つかったキーワードの長さ。見つからない時は -1が入ります。

** 文字を数える時の単位について
o 戻り値や、変数 RSTART、RLENGTHに設定する値の単位は、処理系によって異なります。
   + (漢字などの全角文字が混じっている場合、長さが変わります。)
   + Gawk系は、文字数で数えます。
      + Gawk on Windows 3.1.7
      + Gawk for Windows 3.1.6
   + その他は、バイト数で数えます。
      + mawk MBCS (32bit版) 1.3.3
   + 但し、全角文字を使うと、結果不正になる事のある処理系もありました。
      + Mawk for Windows 1.3.3
      + original = the one true awk(updated May 1, 2007)

** Gawk拡張引数「検索結果詳細」について
o 例えば、次のように書いた時、検索条件で見つかった値を、簡単に取り出す事が出来ます。
--------
BEGIN {
  match("ミクさんの誕生日は8月31日です。", /([0-9]+)月([0-9]+)日/, a);
  for (i in a) {
    print "a[" i "] = [" a[i] "]";
  }
}
--------

o a[0]には、検索条件で見つかった値が入ります。開始位置と長さも取得出来ました。
    + a[0] = [8月31日]
    + a[0 start] = [10] -- 見つかった文字列の開始位置
    + a[0 length] = [5] -- 長さ
o a[1]には、検索条件内に書いた「1つ目の丸括弧」に相当する値が入ります。
    + a[1] = [8]
    + a[1 start] = [10]
    + a[1 length] = [1]
o a[2]には、検索条件内に書いた「2つ目の丸括弧」に相当する値が入ります。
    + a[2] = [31]
    + a[2 start] = [12]
    + a[2 length] = [2]


**** 使用例
--------
BEGIN {
n = match("ミクさん、おはようございます。ミクさん。", /ミクさん/); # 1
print "位置 = " RSTART; # 1
print "長さ = " RLENGTH; # 4 (or 8)
print n "番目で見つかりました。";

n = match("おはようございます。ミクさん。", /ミクさん/); # 11 (or 21)
print "位置 = " RSTART; # 11 (or 21)
print "長さ = " RLENGTH; # 4 (or 8)
print n "番目で見つかりました。";

n = match("おはようございます。ミクさん。", /MEIKOさん/); # 0
print "位置 = " RSTART; # 0
print "長さ = " RLENGTH; # -1
print n "番目で見つかりました。";
}
--------

o 行末のセミコロンは、C言語の書き方に合わせました。無くても動きます。


**** 機能
o 2番目に指定した正規表現を使って、1番目の文字列を検索します。
o 先頭で見つかった時、1を返します。
   + 先頭は0ではありません。JavaScriptに慣れている方は、要注意です。
o 見つからなかった時、0を返します。
o 検索結果を、変数 RSTARTRLENGTHに設定します。見つかった位置と長さです。
o 複数見つけた時、先頭に最も近い位置を返します。

o 文字列の代わりに数値を指定すると、数値を文字列に変換してから使用します。
   + 長い整数を指定すると、最後の方の桁が0になったり、浮動小数点形式になります。
   + 実数を指定すると、6桁までに丸めたり、浮動小数点形式になります。
   + この動作は変える事も出来ます。詳しくは、「数値から文字列にする時に、実数を7桁以上表示させる方法

** 処理系に依存するかもしれない動作
o 検索対象文字列を文字列を使って指定した時も、正規表現として認識されました。但し、仕様としては明記されていません。

** 処理系に依存する動作
o 文字を数える時の単位は、処理系によって異なります。
   + 文字数で数える処理系
      + Gawk on Windows 3.1.7
      + Gawk for Windows 3.1.6
   + バイト数で数える処理系
      + mawk MBCS (32bit版) 1.3.3
   + バイト数で数える処理系、かつ全角文字を使うと結果不正になる事のある処理系
      + Mawk for Windows 1.3.3
      + original = the one true awk(updated May 1, 2007)


**** 確認した処理系
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
    ▼制作メモ
    > substr = 文字列の一部を取り出す
    int = 実数や文字列を整数化する
    strtonum = 10進数、8進数、16進数の文字列を数値に変換する
    +
    RSTART = match関数で見つけた文字列の先頭位置
    RLENGTH = match関数で見つけた文字列の長さ
    IGNORECASE = 文字列比較の時に、大文字小文字を区別させない(Gawk専用)
    index = 文字列の登場位置を調べる
    length = 文字列や配列の長さを調べる
(2010年9月3日追加。Gawk拡張の引数3)