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」カテゴリの記事
- [Linux] ログイン画面のOS名表示など(2013.08.12)
- CentOSからWin7の共有フォルダへアクセス(2011.11.27)
- namazuのインストール手順(2011.09.02)
- mknmzで、エラー 'sh: line 1: no: command not found'(2011.08.30)
- PostgreSQL 8.1から7.3へデータ移行(2011.08.24)