2010年9月2日木曜日

$1 = 最後に読み込んだデータの1列目 - AWK

AWKの入出力関数とコマンド実行機能
△(注記あり)Gawk on Windows △(注記あり)Gawk ○mawk32 ○Mawk △(注記あり)awk
最後に読み込んだデータの1列目です。
o 値を代入すると、$0にも自動反映されます。その動きを利用した、$1 = $1という小技があります。

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

o $1は変数です。値を代入する事も出来ます。
o 設定したい値 -- 文字列です。配列を指定する事は出来ません。
   + 数値を指定すると、文字列に変換されます。
   + この時、mawk系は、実数の値を、変数 CONVERTの値に従って文字列に変換します。
   + Gawkと Original(= the one true awk)では、"%.6g"固定みたいです。(変数 CONVERTや OFMTの値は、参照しません。)
   + 内部的には数値としての値も持っていますが、文字列として表示されます。


**** 使用例
o AWK特有の表現、$1 = $1についてです。
o その1。重複する空白文字やタブを、半角空白1つに置き換える
--------
{
  if (NF > 0) { # 空行でない時に
    gsub(/ /," "); # 全角空白を、半角空白に変更します。
    $1 = $1; # 間接的に、$0の作り直しを要求します。変数 OFSの初期値は " "
  }
  print;
}
--------


o その2.カンマ区切りをタブ区切りに変える。簡易版
--------
BEGIN {
  FS = ","; # 入力はカンマ
  OFS = "\t"; # 出力予定はタブ文字
}
{
  if (NF > 0) { # 空行でない時に
    gsub(/\t/," "); # 読み込んだ行 $0 の中にタブ文字があれば、半角空白に置き換えます。
    $1 = $1; # 間接的に、$0の作り直しを要求します。
  }
  print;
}
--------

o このプログラムは、データ中に文字列形式("aa""a")、カンマ、改行文字が無い事を仮定しています。
o 行末のセミコロンは、C言語の書き方に合わせました。無くても動きます。


**** 機能
o 最後に読み込んだデータの、1列目が入っています。
   + 2列目のデータは $2に入っています。、3列目は $3。
o 改行文字や列区切り文字は入っていません。
   + 読み込み時の列区切り文字を、変更する事が出来ます。変数 FSを使います。
   + 改行文字も、変更する事が出来ます。変数 RSを使います。
o この変数や $2などに値を代入すると、変数 $0や、変数 NFにも自動反映されます。
   + 値の変更内容は、変数 $0にも反映されます。
   + 変数 $0の列区切り文字部分が、変数OFSの値に置き換わります。
   + $1 = $1のように同じ値を代入しても、同じ動きをします。
   + 変数NFの値が変化する事もあります。NFの値を超える列に代入した時です。
     + 例えば、NF = 0の時に $1 = "a"を実行すると、NF = 1になります。

次の操作は、$1の値を変更します。
   + getlineを、引数無しで呼び出した時
   + gsub, subを、$1を指定して呼び出した時
   + $0の値を変更した時で、その変更が1列目に及ぶ時
   + $1の値を直接上書きした時

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

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

** 処理系に依存する動作
o $1に実数を設定する時、処理系によって動作が変わります。
o 変数 CONVFMTの値を使って変換を行う処理系
   + mawk32 1.3.3
   + Mawk for Windows 1.3.3
o 常に同じ精度("%.6g")で変換を行う処理系(= 専用の変数があるのかもしれません)
   + Gawk on Windows 3.1.7
   + Gawk for Windows 3.1.6
   + original = the one true awk(updated May 1, 2007)


**** メモ
o mawk系以外で実数の表示桁数調節をしたい時は、一旦文字列にしてから$1などに代入する方法が簡単です。


**** 確認した処理系
o Gawk on Windows 3.1.7 -- CONVFMT無効
o Gawk for Windows 3.1.6 -- CONVFMT無効
o mawk MBCS (32bit版) 1.3.3
o Mawk for Windows 1.3.3
o original = the one true awk(updated May 1, 2007) -- CONVFMT無効


==
関連ページ:
    ▼AWKの入出力関数とコマンド実行機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > NF = 最後に読み込んだ行の列数
    RT = 最後に読み込んだ行の改行文字(Gawk専用)
    FNR = 現在読み込み中のファイルから読み込んだ行数
    +
    ファイルからデータを読み込む
    $0 = 最後に読み込んだデータ、1行分
    ▼AWKの文字列操作関数と関連機能
(2010年9月9日追加。機能欄で、$1=$1も使える)
(2010年9月2日追加。実数を代入した時の動作)