« grepで、パターンを含まないオプションは「-v」 | トップページ | Googleロゴ - 高柳 健次郎の誕生日 »

2011年1月20日 (木)

awkのメモ

awkの使い方メモ。
以前、自分で作成したメモから転載。

使い方

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

awkは、データをレコード単位で読み込み、パターンに一致したレコードに対して、アクションを実行する。

パターン

アクションを行うレコード(行)を指定する。

  • レコード中に含まれる文字列を正規表現で指定(/文字列/の形式)
  • 特殊なパターン(BEGIN/END)
  • 条件式

2つのアクションをカンマ(,)で区切ることにより、処理開始レコードと処理終了レコードを指定できる。('/MIKA/,/TOMOKO/{print $1,$4}' …最初に見つかった「MIKA」を含むレコードから、最初に見つかった「TOMOKO」を含むレコードまでが処理対象)

パターンを省略した場合、すべてのレコード(行)に対して、アクションを実行する。

アクション

処理内容を指定する。

  • フィールド(列)の出力
  • 変数の代入
  • 計算式

アクションを複数記述するときにはセミコロン(;)で区切る。(パターン{アクション1;アクション2}

アクションを省略した場合、パターンに一致したレコード(行)をすべて表示する。

レコード

レコードセパレータで区切られた文字列。
デフォルトのレコードセパレータは「改行」なので、1レコードは1行となる。

フィールド

フィールドセパレータで区切られた文字列。
デフォルトのフィールドセパレータは「半角スペース」または「タブ」なので、1フィールドは1単語となる。
現在処理中レコードの各フィールドは、左から「$1」、「$2」、、、であらわし、1レコード全体は「$0」であらわす。

レコードやフィールドは「組込み変数」で制御されている。したがって、変数の値を処理開始前に設定することで、区切りを変更できる。

例1:基本的な処理

$ cat member.txt
Line1 : YOUHEI    m s42-10-06
Line2 : MIKA      w s36-07-21
Line3 : AYUMI     w s39-05-07
Line4 : TADAO     m s41-08-18
Line5 : TOMOKO    w s40-01-07
Line6 : MITSUYASU m s41-05-30

$ awk '/w/{print $5,$3}' member.txt ←パターン「/w/」(wという文字列を含むレコードのみ処理)
s36-07-21 MIKA                         アクション「print $5,$3」(第5、第3フィールドを表示)
s39-05-07 AYUMI
s40-01-07 TOMOKO

$ awk '{print $5,$3}' member.txt ←パターン省略(すべてのレコードを処理)
s42-10-06 YOUHEI                    アクション「print $5,$3」(第5、第3フィールドを表示)
s36-07-21 MIKA
s39-05-07 AYUMI
s41-08-18 TADAO
s40-01-07 TOMOKO
s41-05-30 MITSUYASU

$ awk '/w/' member.txt     ←パターン「/w/」(wという文字列を含むレコードのみ処理)
Line2 : MIKA w s36-07-21      アクション省略(すべてのフィールド(レコード全体)を表示)
Line3 : AYUMI w s39-05-07
Line5 : TOMOKO w s40-01-07

例2:ちょい複雑な表示

$ cat address.txt
HATTORI   tokyo    03-1234-5678  hattori@foo.com  mail
SUZUKI    chiba    0471-987-6543                  tel
TAKAHASHI kanagawa 044-5555-5555 taka@bar.co.jp   mail
HORI      tokyo    03-9999-1000  hori@sys.foo.com tel

$ awk '/mail/{print $1,$4} /tel/{print $1,$3}' address.txt
↑「mail」を含むレコードは、第1、第4フィールドを表示「tel」を含むレコードは、第1、第3フィールドを表示
HATTORI hattori@foo.com
SUZUKI 0471-987-6543
TAKAHASHI taka@bar.co.jp
HORI 03-9999-1000

$ cat renraku.txt    ←スクリプトファイル
/mail/{print $1,$4}
/tel/{print $1,$3}
↑1行に1つの「パターン{アクション}」' 'は記述しない

$ awk -f renraku.txt address.txt  ←スクリプトファイルを利用して処理を実行
HATTORI hattori@foo.com
SUZUKI 0471-987-6543
TAKAHASHI taka@bar.co.jp
HORI 03-9999-1000

例3:printアクションで固定文字列指定

$ cat address.txt
HATTORI   tokyo    03-1234-5678  hattori@foo.com  mail
SUZUKI    chiba    0471-987-6543                  tel
TAKAHASHI kanagawa 044-5555-5555 taka@bar.co.jp   mail
HORI      tokyo    03-9999-1000  hori@sys.foo.com tel

$ awk '{print "name --> " $1 " : addr --> " $2}' address.txt

name --> HATTORI : addr --> tokyo
name --> SUZUKI : addr --> chiba
name --> TAKAHASHI : addr --> kanagawa
name --> HORI : addr --> tokyo

↑固定文字列はダブルクォーテーション(")で囲む
  printアクション中では、固定文字列以外で半角スペースを空けても、何も表示されない($1の前後とか)
  ちなみに、例1、例2などカンマ(,)区切りでフィールドを並べたが、この場合は、半角スペース1つ表示される $ awk '{printf("name --> %-10s : addr --> %-9s\n", $1, $2)}' address.txt name --> HATTORI    : addr --> tokyo name --> SUZUKI     : addr --> chiba name --> TAKAHASHI  : addr --> kanagawa name --> HORI       : addr --> tokyo ↑printf関数もある!!

変数

awkでは、ユーザが任意に利用できる「ユーザ変数」と、あらかじめ設定されている「組込み変数」がある。

ユーザ変数
  • 整数100を代入する … {data=100}
  • 文字列minnyを代入する … {data="minny"}
  • 表示する … {print data}
組込み変数
変数名 意味 デフォルト値
FS 入力時のフィールドセパレータ。(Field Separator) 半角スペースおよびタブ
RS 入力時のレコードセパレータ。(Record Separator) 改行
NF 処理中のレコード内のフィールドの個数。(Now Field) 現在値
NR 処理中のレコード番号(行番号)。(Now Record) 現在値
$ cat hello.c
#include <stdio.h>

void main(void)
{
  printf("Hello World\n");
}

$ awk '{print NR ": " $0}' hello.c
1: #include <stdio.h>
2:
3: void main(void)
4: {
5: printf("Hello World\n");
6: }
↑$0(レコード全体)の前に変数「NR」(現在行番号)を表示


$ cat address.txt
HATTORI   tokyo    03-1234-5678  hattori@foo.com  mail
SUZUKI    chiba    0471-987-6543                  tel
TAKAHASHI kanagawa 044-5555-5555 taka@bar.co.jp   mail
HORI      tokyo    03-9999-1000  hori@sys.foo.com tel

$ awk '{print NF}' address.txt
5
4
5
5

前処理と後処理(BEGIN/END)

前処理(BEGIN)

最初のレコードを読み込む前に、アクションを実行する。

'BEGIN{FS=":"}' … FS(フィールドの区切り)をコロン(:)に設定

後処理(END)

全てのレコードを読み終えた後に、アクションを実行する。

'END{print "total: " NR " records"}'

$ cat fstest.txt
HATTORI:tokyo:03-1234-5678
TANIGUCHI:kanagawa:09-8765-4321

$ awk 'BEGIN{FS=":"} {print $2}' fstest.txt ←FS(フィールド区切り)をコロン(:)に設定し、全レコードの第2フィールドを表示

tokyo
kanagawa

$ awk -F':' '{print $2}' fstest.txt ←FS(フィールド区切り)の変更は「-F」オプションでも可能
tokyo
kanagawa


$ cat rstest.txt
HATTORI tokyo 03-1234-5678

$ awk 'BEGIN{RS=" "} {print NR ":" $0}' rstest.txt  ←RS(レコード区切り)をスペースに設定し、全レコードを表示

1:HATTORI
2:tokyo
3:03-1234-5678

演算子

パターン部に条件式を記述することが可能。この際には、比較演算子や論理演算子を利用する。

比較演算子
演算子 意味
== 等しい $1=="mickey"
!= 等しくない $3!=1800
< より小さい NF<5
> より大きい $>100
<= 以下 $1<=10
>= 以上 NR>=3
論理演算子
演算子 意味
&& 論理積 $2="OK"&&$3=="NO"
|| 論理和 $3=="OK"||$4="OK"
算術演算子

アクション部には変数の算術演算を記述できる。

演算種類 演算子 意味
二項演算 + - * / % など 四則演算
単項演算 + - など 符号
代入演算 = += *= など 代入

« grepで、パターンを含まないオプションは「-v」 | トップページ | Googleロゴ - 高柳 健次郎の誕生日 »

Linux」カテゴリの記事

2019年11月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Amazonリンク

ダイビング写真(swf)

ブログ内検索

  • Google
    WWW を検索
    ブログ内を検索

リンク(いつもお世話さま)

  • ソニーストア
     iTunes Store(Japan)
    Just MyShop(ジャストシステム)
    ブックオフオンライン
無料ブログはココログ