#author("2021-11-19T02:44:39+09:00","default:Miyashita","Miyashita")
#author("2023-08-07T12:51:09+09:00","default:Miyashita","Miyashita")
*awk メモ [#yd994133]
#contents
awk は AWK という言語らしい.~
列ごとに変数が並んだファイルを手早く処理したいときに便利.~
~

**列ごとに値を抽出 [#u6e7a758]
下記のようなファイルを仮定する。
 ## foobar.txt,  $x, $y, $a, $z
 x1, y1, a1, z1, 
 x2, y2, a2, z2,
 x3, y3, a3, z3,
 ...
この並びのファイルをaの列だけ取り除くには,
#codeprettify(lang-awk){{
awk -F',' 'NR>1 {print $1 $2 $4}' foobar.txt > output.txt
}}
とする.ここで, -F',' はセパレータが「,」であること,NR は行を表し,NR>1 で1行目のヘッダーを読み飛ばす,${d} はそれぞれの列を表す.~

以下のように,printf で出力フォーマットの指定も可能.
#codeprettify(lang-awk){{
# 2列目と4列目を %12.5f で出力
awk '{printf "%12.5f %12.5f\n", $2, $4}' foobar.txt
}}
~
~

**最大値・最小値の抽出 [#gd7c8518]
z の最大値・最小値を抽出することを考える.~
全ての行に対して,大小判定を行うようにすれば OK.
#codeprettify(lang-awk){{
#初期値(99999)は都合に応じて変更する
#最小値
awk -F',' 'BEGIN{min=99999} {if (min>$4) min=$4} END {printf "%0.1f",min}' foobar.txt >foobarmin.txt 
#最大値
awk -F',' 'BEGIN{max=-99999} {if (max<$4) max=$4} END {printf "%0.1f",max}' foobar.txt >foobarmax.txt
}}
初期値を設定しておかないと,全てが0以上または0以下の場合値を返さないことに注意.~
~
~

**NaNのある行を取り除く(isnan的な) [#z8852e64]
awk で NaN を検出して,該当する行全体を除いたファイルを作成する.~
まず,下記のようなfoobar.datを仮定する.
   1  1  5.000
   1  2  1.000
   1  3    NaN
   2  1  3.000
   2  2    NaN
   2  3  4.000
ここから,3 列目に NaN のある行だけ除いて,新たにファイルを作成にはパターンマッチを行う処理を加えて,
#codeprettify(lang-awk){{
awk '!/NaN/{print $0}' foobar.dat > foo.dat
}}
とする.生成されたfoo.datは下記の通り.
   1  1  5.000
   1  2  1.000
   2  1  3.000
   2  3  4.000
NaNのない行だけ抜き出すことができた.~
~
~

**行指定 [#pb7a4e56]
#codeprettify(lang-awk){{
awk 'NR==1,NR==5 {print $1 $2}' foobar.txt
}}
とすると,1行目から5行目までを print することになる.~
確認やテストを実行する時に使える.~
~
~
** n 行おきに処理(間引き) [#s6b49c79]
データを間引きして 10 行おきに出力するなら
#codeprettify(lang-awk){{
awk '{ NR%10==0 {print $1 $2}' foobar.txt
}}
ヘッダー読み飛ばしもするときは if を使う.
#codeprettify(lang-awk){{
awk '{ if (NR>1 && NR%10==0) {print $1 $2} }' foobar.txt
}}
出力対象の行をずらすときは NR%10==0 を NR%10==1 とかにすればよい.
~
~

** n 列目の文字が hoge になっている行だけを抽出 [#p337da07]
1 列目が hoge になっている行だけを抜き出す場合.
#codeprettify(lang-awk){{
awk '$1 == "hoge" {print}' foobar.txt
}}
~
1 列目が hoge になっている行の 2,3 列目を抜き出す場合.
#codeprettify(lang-awk){{
awk '$1 == "hoge" {print $2, $3}' foobar.txt
}}
~
~

** n 列目の数値が何らかの条件式を満たす行だけを抽出 [#u81fc5f1]
上と同様.文字列が数値になっただけ.
#codeprettify(lang-awk){{
awk '$1 > 0 {print $2, $3}' foobar.txt
}}
ヘッダー1行を読み飛ばしてこれを適用するときは,条件式に if をつける.
#codeprettify(lang-awk){{
awk 'NR>1 { if ($1 > 0) {print $2, $3} }' foobar.txt
}}
~
~

**(環境)変数などの値を使う [#z78522ef]
awk 外からもってきた何らかの数値を使いたいときは -v オプション.
#codeprettify(lang-awk){{
# $VAL_SHELL は shell 上の変数
awk -v val=$VAL_SHELL 'NR>1 { if ($1+val > 0) {printf "%12.5f %12.5f\n", $1+val, $2} }' foobar.txt
# $VAR_SHELL は shell 上の変数
awk -v var=$VAR_SHELL 'NR>1 { if ($1+var > 0) {printf "%12.5f %12.5f\n", $1+var, $2} }' foobar.txt
}}
~
~

Front page   Edit Diff Attach Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes