【Linux入門】awkコマンドの基本を学ぶ

今回はファイル処理をワンラインで行う強力な味方、awkコマンドをご紹介。本稿ではawkコマンドの基本的な使い方を解説します。


目次

awkコマンドの用法
awkコマンドを使ってみよう
  特定の列のデータだけ抜き出す
  データの区切り文字をカンマにする
  特定の文字で始まる(含む)行を抜き出す
awkコマンドによる条件付き出力
  数値比較によって絞り込んで出力する
awkコマンドによる簡易数値計算
  列データの最大・最小値を求める
  列データの合計・平均を求める
  整数・実数の桁合わせ(printf関数)
組み込み関数

 awkコマンドの用法

awkコマンドの基本的な使い方は以下のようになります。

$ awk 'パターン {アクション}' ファイル名

(※「$ 」はコマンド受付中のマークです。既に表示されているので皆さんが入力する必要はありません)

パターンというのは何らかの条件と考えておけばOKです。アクションはawkコマンドで行う何らかの操作を指します。awkコマンドは、特定のパターンに合致した行もしくはカラムの要素に対して指定したアクションを実行するコマンドと言えます。

※AWK(オーク)は元々プログラミング言語の一つであり、UnixやLinux環境でファイル操作を簡単に行えるように開発されたものです。ワンラインで色々やるならPerlでもできます。

 

 awkコマンドを使ってみよう

例えば、以下のように「dataset.txt」というファイルにa、b、cの3系列のデータがリストとして書き込まれているとします。

» データセット

1	0.182218988	a
3	0.297784751	a
7	0.360555096	a
8	0.372087519	a
9	0.409256577	a
15	0.565621684	a
17	0.613346197	a
21	0.678362497	a
23	0.714005697	a
26	0.807226012	a
31	0.842764672	a
32	0.847292094	a
36	0.881504968	a
40	0.973405431	a
43	0.987763106	a
46	1.014998976	a
48	1.02223779	a
53	1.094431056	a
54	1.107053052	a
57	1.162548999	a
59	1.22366798	a
61	1.286940823	a
62	1.305921405	a
66	1.440008501	a
68	1.536580082	a
2	0.230268945	b
4	0.306062235	b
5	0.310469045	b
6	0.339786199	b
10	0.469558639	b
12	0.534505967	b
14	0.563187878	b
18	0.616513133	b
19	0.648537306	b
28	0.827033352	b
30	0.838900174	b
34	0.871590963	b
35	0.877929505	b
37	0.900402407	b
44	0.992150485	b
47	1.020659782	b
50	1.074472053	b
56	1.126128635	b
58	1.191423735	b
60	1.230548034	b
63	1.327300318	b
64	1.348933769	b
67	1.456096108	b
11	0.522872415	c
13	0.536040293	c
16	0.597841941	c
20	0.67797903	c
22	0.694680553	c
24	0.773443168	c
25	0.777163356	c
27	0.815538433	c
29	0.82740152	c
33	0.85021772	c
38	0.958370643	c
39	0.962444199	c
41	0.983144472	c
42	0.985217274	c
45	1.014833774	c
49	1.035404769	c
51	1.081017564	c
52	1.087560751	c
55	1.12527036	c
65	1.350717734	c

» 閉じる

例えば、

$ cat dataset.txt | awk '{print}'

とすると全ての行を出力します。これは「awk ‘{print $0}’」としても同じ結果になります。

※「|」は「パイプ」、もしくは「パイプライン」と呼ばれるコマンドの入出力を繋ぐもので、これにより “cat dataset.txt” の出力結果に対して “awk ‘{print}'” という別のコマンドを適用することができます。

3列のデータのうち2列目だけを表示したいとき

$ cat dataset.txt | awk '{print $2}'

とします。

また、系列cのデータだけ抜き出したいとき

$ cat dataset.txt | awk '$3=="c" {print $2}'

とします。awkコマンドの「$3==”c”」という部分が「パターン」に相当します。これは「3カラム目の値($3)が “c” のとき2カラム目の値($2)を表示する」という意味です。

データの出力は複数個指定できて、「awk ‘{print $2 , $3}’」のようにすると2カラム目の値と3カラム目の値が空白で区切られて出力されます。

データの区切り文字をカンマにしたいときは例えば

$ cat dataset.txt | awk '{print $2 ", " $3}'

のようにします。

また、例えば

$ cat dataset.txt | awk '$3=="c" {print}'

11      0.522872415     c
13      0.536040293     c
16      0.597841941     c
20      0.67797903      c
22      0.694680553     c
24      0.773443168     c
25      0.777163356     c
27      0.815538433     c
29      0.82740152      c
33      0.85021772      c
38      0.958370643     c
39      0.962444199     c
41      0.983144472     c
42      0.985217274     c
45      1.014833774     c
49      1.035404769     c
51      1.081017564     c
52      1.087560751     c
55      1.12527036      c
65      1.350717734     c

のように、該当する行を抜き出すこともできます(grepコマンドのように使える)。

awkコマンドではcutコマンドのように区切り文字(delimiter)を指定しなくても良いという強みがあります(指定したい場合は-Fオプションを使う)。また、条件を色々と指定できるのでgrepコマンドより細かい運用も可能なところが魅力です。今までcutコマンドやgrepコマンド、sedコマンドを駆使してデータの整理をしていたのが、awkコマンドではラクラクということも有り得ます。

続いてパターン」部分の実用的な使い方を紹介します。

 

 awkコマンドによる条件付き出力

awkコマンドでは、ある要素に対して数値比較をして絞り込んだ上で出力することが可能です。

例えば、2列目の数値が1より大きい要素を取り出したいときは

$ cat dataset.txt | awk '$2 > 1 {print}'

のようにします。パターンのところに “$2 > 1” と書くことで、2列目の数値と1との大小を比較することができます。

さらに、and条件やor条件も指定可能です。

$ cat dataset.txt | awk '0.5 < $2 && $2 < 1 {print}'

この場合は2列目の数値が 0.5~1 の範囲(0.5 より大きい、かつ 1 未満)にある行がすべて抜き出されます。

2列目の数値が 0.5 未満、もしくは 1 以上である行を抜き出すときは

$ cat dataset.txt | awk '0.5 > $2 || $2 >= 1 {print}'

とします。

このようなタイプの行(または要素)の抽出をgrepコマンドで行うのは難しいですよね。awkコマンドはこうした数値を判別・評価して抜き出したりする操作が得意です。

 

 awkコマンドによる簡易数値計算

awkコマンドを用いることで、各データに対して数値計算を行うことが可能です。

●最大値を求める

2列目のデータの最大値を抜き出します。

$ awk 'NR==1 {max=$2} {if($2 > max) max = $2} END {print max}' dataset.txt

1.536580082

●最小値を求める

2列目のデータの最小値を抜き出します。

$ awk 'NR==1 {min=$2} {if($2 < max) min = $2} END {print min}' dataset.txt

0.182218988

●合計を求める

2列目のデータの総和を計算します。

$ awk '{sum+=$2} END {print sum}' dataset.txt

58.4872

●平均を求める

2列目のデータの平均を計算します。

$ awk '{sum+=$2}END{print sum/NR}' dataset.txt

0.847641

“sum/NR” で変数sumの値を要素数で割ることができます。

●整数・実数の桁合わせ(printf関数)

上記の合計を求めるコマンドでは小数点以下4桁までしか出力されていませんが、printf関数を使えば整数でも小数でもC言語のように桁合わせ可能です。例えば以下のように指定することができます。

$ awk '{sum+=$2} END {printf "%2.8f\n", sum}' dataset.txt

58.48720259

同様に平均の計算でもprintf関数を使えば桁数を調整できます。

printf関数で指定できる書式は以下の通りです。

メタ文字 説明
%c ASCIIの1文字
%d 整数
%nd n桁の整数
%0nd n桁の整数(桁数がnに満たない場合は0で埋める)
%f 浮動小数点
%x.yf 整数部分x桁、小数部分y桁の浮動小数点
%e 指数形式
%o 符号なし8進数
%s 文字列
%ns n文字までの文字列
%% 「%」(”%%”と書くことでエスケープされる)

桁合わせする方法は何かと入用なので意外と使えます。

 

 組み込み関数

awkには次のような組み込み関数が用意されています。これによりデータ処理の幅が広がります。

関数 説明
cos 余弦(コサイン)を返す
exp 指数を返す
getline 次のレコードを読み込む
index 指定した文字列が最初に出現する位置を返す
int 小数点以下を切り捨てた整数を返す
length 文字列の長さ(文字数)を返す
log 自然対数を返す
match 指定した正規表現が最初に出現する位置を返す
sin 正弦(サイン)を返す
split 文字列を配列要素に分解して要素数を返す
sprintf 書式に従って文字列に変換する
sqrt 平方根を返す
substr 部分文字列を返す

 


今回はawkコマンドの基本的な使い方についてまとめました。大規模にデータを整理するシェルスクリプトを書く際に重宝するコマンドの一つで、使い方次第ではもっと色々なことができるので、どんどん使いこなしていきましょう!

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です