プログラム言語 awk Linux/Unix利用者向け一行コマンド



プログラム言語 awk は、入力パターンに応じて色々なアクションを実行することによって、伝統的なデータ処理からプログラムの試作品作りまでのさまざまな仕事を処理できるようにしたファイル処理言語です。

この言語は、1行か2行の短いプログラムで驚くほど広範囲の処理ができます。非会話型ストリームエディタ sed などと利用することで、非常に便利です。

スポンサードリンク

コマンド形式

awk は、ある程度複雑なプログラムを書くのにも利用できますが、パイプで繋げて記述することでデータ処理に便利です。

記述方法は次のようになります。

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

ただし、連続処理で利用する場合は次のように利用する方が便利でしょう。

% 処理コマンド(対象データを出力) | awk 'パターン {アクション}' | 処理コマンド.... et al.

パターンには正規表現が利用できます。

また特別なパターンとして BEGIN と END があります。

ある程度複雑なプログラムの場合は、ファイルに保存して次のようなコマンドで利用できます。

% awk -f プログラムを記述したファイル名 対象ファイル名

組み込み変数には次のようなものがあります。

組み込み変数名意味デフォルト値
FS入力のフィールド区切り文字スペース
RS入力のレコード区切り文字改行(\n)
OFS出力時のフィールド区切り文字スペース
ORS出力時のレコード区切り文字改行(\n)
NFレコード中のフィールド数現在の入力レコード中のフィールド数
NR入力中のレコード数現在の入力ファイル数のレコード数
ARGC引数の個数
ARGV引数(配列)
ENVIRON環境変数を収めた連想配列。
例)環境変数LANGならばENVIRON["LANG"]と参照できる
FILENAME現在処理しているファイルの名前

オプションには次のようなものがあります。

オプション 意味
-f ファイル名 awkスクリプトが書かれたファイルを指定する
-F 区切り文字 区切り文字を指定する(デフォルトは空白文字)
-v 変数名=値 変数を定義する

また、組み込み関数には次のようなものがあります。

スポンサードリンク

1行プログラミング

awk でデータの単純なフォーマット変換することを目的としています。

まず、次のようなデータ(/tmp/a とします)に対して、処理を行うことを考えます。

 1 2 3 4
-5 6 7 8 0
9 10 113

入力行の総数を印字する

入力行の総数を出力します(他の方法 cat /tmp/a | wc)。

cat /tmp/a | awk 'END {print NR }'

実行結果

3

N行目の入力行を印字する

3行目の入力行を出力します(他の方法 cat /tmp/a | head -3 | tail -1)。

cat /tmp/a | awk 'NR==3'

実行結果

9 10 113

N個より多い欄を持つすべての入力行を印字する

1 行に3 個以上のデータが記述されている行をすべて出力する。

% cat /tmp/a | awk 'NF > 3 {print}'

実行結果

1 2 3 4
-5 6 7 8 0

すべての入力行の最後の欄を印字する

すべての入力行の最後の欄を印字する。

% cat /tmp/a | awk '{print $NF}'

実行結果

4
0
113

最後の行の最後の欄を印字する

最後の行の最後の欄を印字する。

% cat /tmp/a | awk '{field = $NF } END {print field }'

実行結果

113

すべての行の欄を逆順で印字する

1行ごとに逆順にソートして表示します。

% cat /tmp/a | awk '{for(i=NF; i>0; i--) printf("%s ",$i); printf("\n"); }'

実行結果

4 3 2 1
0 8 7 6 -5
113 10 9

列を指定して表示する

1列、3列、2列のみを表示する

% cat /tmp/a | awk '{ print $1,$3,$2 }'

実行結果

1 3 2
-5 7 6
9 113 10

行を指定して表示する

2行~3行を表示する

% cat /tmp/a | awk 'NR==2,NR==3 { print }'

実行結果

-5 6 7 8 0
9 10 113

すべての行で指定した列を除いて表示する

すべての行で2列目を除いて表示します。

% cat /tmp/a | awk '{ $2=""; print }'

実行結果

1  3 4
-5  7 8 0
9  113

各欄の値を絶対値に置き換えてからすべての行を印字する

各欄の値を絶対値に置き換えてからすべての行を印字します。

% cat /tmp/a | awk '{ ($n < 0) ? $n = -$n : $n = $n; print }'

実行結果

1 2 3 4
5
9 10 113

任意の語を含む行を印字する

「1」が含まれる行の1列目を表示する

% cat /tmp/a | awk '/1/{ print $1}'

実行結果

1
9

少し複雑な1行プログラミング

まず、次のようなデータ(/tmp/b とします)に対して、処理を行うことを考えます。

1, 2, 3
4, 5, 6
7, 8, 9

任意の文字を削除して表示する

「,」を削除して表示します(他の方法 cat /tmp/b | sed 'y/,/ /')。

% cat /tmp/b | awk 'BEGIN { FS=","} {print $1,$2,$3}'

実行結果

1  2  3
4  5  6
7  8  9

デリミタ(区切り文字)を複数指定する

次のようなデータ(/tmp/c とします)に対して、処理を行うことを考えます。

"1","2","3"
"4","5","6"
"7","8","9"

デリミタを複数指定する場合は、「[](カギカッコ)」で囲う事で-Fで指定することができます。

% cat /tmp/c | awk -F'[","]' '{print $2,$5,$8}'

実行結果

1  2  3
4  5  6
7  8  9

各列のすべての行を合計して、その値を印字する

各列のすべての行を合計して、その値を表示します。

% cat /tmp/b | awk 'BEGIN { FS=","} { x+=$1;y+=$2;z+=$3 } END{ print x,y,z }'

実行結果

12 15 18

各列のすべての行を平均して、その値を印字する

各列のすべての行を平均して、その値を表示します。

% cat /tmp/b | awk 'BEGIN { FS=","} { x+=$1;y+=$2;z+=$3 } END{ print x/NR,y/NR,z/NR }'

実行結果

4 5 6

grep/sed/awk/Perl/Pythonで利用できる正規表現のまとめ

各スクリプト・コマンドでよく利用される正規表現の比較をまとめています。

grepsedawkPerlPython
.....
*****
^^^^^
$$$$$
¥( ¥)¥( ¥)( )( )( )
\1 \2 \3\1 \2 \3\1 \2 \3\1 \2 \3\1 \2 \3
[ ][ ][ ][ ][ ]
¥{n, m¥}¥{n, m¥}{n, m}{n, m}{n, m}
¥{n, ¥}¥{n, ¥}{n, }{n, }{n, }
¥{n¥}¥{n¥}{n}{n}{n}
\+\++++
\????
\|\||||

オススメ書籍

人気の高い書籍および参考文献を紹介します。

スポンサードリンク

スポンサードリンク