awk コマンド基本操作

bash
bashLinux

setは置換、grepは検索、awkは列の抽出が得意としているので、この3つを組み合わせてゴニョゴニョすれば大抵のこと事足りる、と思っています。
今回はawkコマンドの基本操作を抑えていきましょう。

基本中の基本の型はこちらです。

awk ‘パターン {アクション}’

文字列を抽出する

スペース区切りのサンプルファイルを用意しました。

$ cat sample.txt 
Apple 5.00 12
Banana 3.34 5
Kiwi 2.87 15
Pineapple 6.02 3

1番目フィールドを抽出するときは$1, 2番目は$2, 3番目は$3と指定します。
全ての列を抽出するときは$0を指定します。

# 1番目と2番目のフィールドを抽出します
$  awk '{print $1,$2}' sample.txt 
Apple 5.00
Banana 3.34
Kiwi 2.87
Pineapple 6.02
 
# 全てのフィールドを抽出します
$  awk '{print $0}' sample.txt 
Apple 5.00 12
Banana 3.34 5
Kiwi 2.87 15
Pineapple 6.02 3

抽出条件を与える

条件に一致する行のフィールドを抽出します。
条件が複数ある場合は、AND演算子「&&」やOR演算子「||」で繋いで行きます。
条件式の部分を()で括ってもいいですし、括らなくてもOKです。
また、全てのフィールドを抽出する場合は、アクションの記述を省略することがきます。

# 3番目のフィールドの数字が10より大きい場合、全てのフィールドを抽出する
$  awk '$3 > 10 {print $0}' sample.txt 
Apple 5.00 12
Kiwi 2.87 15

# 3番目のフィールドの数字が10より大きく、かつ1番目のフィールドかAppleではない場合、全てのフィールドを抽出する
$  awk '($3 > 10 && $1 != "Apple") {print $0}' sample.txt 
Kiwi 2.87 15
$  awk '$3 > 10 && $1 != "Apple" {print $0}' sample.txt 
Kiwi 2.87 15

# アクションの記述を省略した書き方
$ awk '$3 > 10 && $1 != "Apple"' sample.txt
Kiwi 2.87 15

抽出したフィールド(列)を計算につかう

抽出した数値を計算に使用し、その結果を出力させます

# 1番目のフィールドと2番目のフィールドを掛けた結果を出力させます
$ awk '{print $1, $2*$3}' sample.txt 
Apple 60
Banana 16.7
Kiwi 43.05
Pineapple 18.06

複数のファイルに対してawkコマンドをつかう

こちらも簡単、複数のファイルを指定してやるだけです。
sample2.txtというファイルを用意しました。
sample.txtとsample2.txtから1番目と2番目の列を抽出します。

$ cat sample2.txt
Orange 3.00 20
Strawberry 1.00 50

# sample.txtとsample2.txtから1番目と2番目のフィールドを抽出
$ awk '{print $1,$2}' sample.txt sample2.txt 
Apple 5.00
Banana 3.34
Kiwi 2.87
Pineapple 6.02
Orange 3.00
Strawberry 1.00

最後のフィールド(列)を抽出する:NF変数

各行によってフィールド数が異なっていたり、そもそもフィールド数が分からない(目視で数えるのは無理)というような場合があります。こうゆうときNF変数が便利です。
こうゆうサンプルを用意しました。

$ cat sample3.txt 
0 0 0 0 0 1 10
0 0 0 0 0 0 2 20
0 0 0 0 0 0 0 3 30

「$NF」で最後のフィールドを指定できます。
また、紛らわしいですが「NF」とするとフィールド数を表します。

# 最後のフィールドを表示する
$ awk '{print $NF}' sample3.txt 
10
20
30

# 最後から2番目のフィールドを表示する
$ awk '{print $(NF-1)}' sample3.txt 
1
2
3

# 最後のフィールドの値から1引いた数を表示する
$ awk '{print $NF-1}' sample3.txt 
9
19
29

# 各行のフィールド数を表示する
$ awk '{print NF}' sample3.txt 
7
8
9

# 各行のフィールド数から1引いた数を表示する
$ awk '{print NF-1}' sample3.txt 
6
7
8

# フィールド数が8個より大きい行の全フィールドを表示する
$ awk 'NF > 8' sample3.txt
0 0 0 0 0 0 0 3 30

紛らわしいですね。注意してくださいね。

区切り文字を指定する

区切り文字を指定しない場合は、「スペース」と「タブ」両方の区切りとなります。
下記のようなサンプルファイルを用意しました。
1行の中に「スペース」「:」「,」「タブ(TAB Insertの前)」が含まれています。
区切り文字を指定して抽出してみましょう

$ cat split.txt 
$1:Mac Baseball,7000,AA TAB Insetrt
$2:Mary Tennis,5000,AB  TAB Insetrt
$3:Dan Football,8700,BB TAB Insetrt

「,」「:」「タブ」で区切った場合の2番目のフィールドを抽出する。

# カンマ区切りの第2フィールドを抽出する
$ awk -F, '{print $2}' split.txt 
7000
5000
8700

$ awk -F "," '{print $2}' split.txt  # この書き方でもOK
7000
5000
8700

# コロン区切りの第2フィールドを抽出する
$ awk -F: '{print $2}' split.txt 
Mac Baseball,7000,AA	TAB Insetrt
Mary Tennis,5000,AB	TAB Insetrt
Dan Football,8700,BB	TAB Insetrt

$ awk -F ":" '{print $2}' split.txt    # この書き方でもOK
Mac Baseball,7000,AA	TAB Insetrt
Mary Tennis,5000,AB	TAB Insetrt
Dan Football,8700,BB	TAB Insetrt

# タブ区切りの第2フィールドを抽出する
$ awk -F\t '{print $2}' split.txt   
TAB Insetrt
TAB Insetrt
TAB Insetrt

$ awk -F "\t" '{print $2}' split.txt 
TAB Insetrt
TAB Insetrt
TAB Insetrt

複数の区切り文字を指定する

「:」と「,」の両方で区切ります。

$ awk -F [:,] '{print $2}' split.txt 
Mac Baseball
Mary Tennis
Dan Football

printfを使ってフォーマット形式で表示する

printfを使って整形した文字列を表示することもできます。
こんなサンプルを用意しました。

$ cat sample4.txt 
SATO,1200,25
TANAKA,1000,35
YAMADA,1600,40

名前、時給、勤務時間のcsvファイルです。
それぞれの給与を見やすく形成して表示してみましょう。

$ awk -F, '{printf("%-8s さんの今月の給与は %8.2f です。\n", $1, $2*$3)}' sample4.txt 
SATO     さんの今月の給与は 30000.00 です。
TANAKA   さんの今月の給与は 35000.00 です。
YAMADA   さんの今月の給与は 64000.00 です。

コメント

タイトルとURLをコピーしました