「Awk」の版間の差分
提供: Wikinote
細 (→関数) |
|||
(同じ利用者による、間の18版が非表示) | |||
行1: | 行1: | ||
− | + | 手軽さとパワーのバランスが素晴らしい AWK について。 | |
− | ** [http://www.kt.rim.or.jp/~kbk/gawk/gawk_toc.html The GAWK Manual] (2.15.6) | + | |
− | + | ちなみに、AWK の A は、(オレの好きな) かの有名な Aho-Corasick 法を作った | |
− | + | Aho 氏の A である!K はカーニハン。そりゃいい言語だわな。 | |
− | awk [-F sep] ' | + | |
− | * | + | == 参考文献 == |
− | ** | + | * [http://www.gnu.org/software/gawk/manual/gawk.html The GNU Awk User's Guide] (3.1.6) — 本家のマニュアル |
− | + | * [http://www.kt.rim.or.jp/~kbk/gawk/gawk_toc.html The GAWK Manual] (2.15.6) | |
− | + | * [http://www.kt.rim.or.jp/~kbk/gawk-30/index.html AWK Language Programming] (3.0.4) | |
− | + | ||
− | + | == 覚え書き == | |
− | + | ||
− | + | === コマンド構文 === | |
− | + | awk [-F sep] [-f progfile] [-v name=value] 'program' [file ...] | |
− | + | ||
− | + | * セパレータ (デリミタ) は -F で指定することに注意 | |
− | + | * -f で自作ライブラリを複数取り込める | |
− | + | * -v で変数を渡す | |
− | + | ||
− | + | === 組み込み変数 === | |
− | + | * FS ― フィールドセパレータ (デフォルトはスペース) | |
− | + | * NR ― 現レコード数 | |
− | + | * NF ― フィールド数 | |
− | + | * OFS ― 出力フィールドセパレータ (print のカンマ区切りのセパレータ; デフォルトはスペース) | |
− | + | * ORS ― 出力レコードセパレータ (デフォルトは改行) | |
− | * | + | |
− | ** | + | === 演算子 === |
− | * | + | * ~ ― 正規表現にマッチしたら真 ($0 ~ /re/) |
− | ** <code>{ print $0 | + | 他はほぼ C と同じ |
− | ** | + | |
− | + | === 制御構文 === | |
− | + | * <code>break</code>, <code>continue</code> ― for や while の中で使う | |
+ | * <code>next</code> ― 次のレコードへ処理を移す | ||
+ | * <code>exit</code> ― 残りのレコードは見ないで処理を中断 (END の中は実行されるので注意) | ||
+ | |||
+ | === 配列 === | ||
+ | * <code>array[i]</code> ― 一次元配列 | ||
+ | * <code>array[i,j,k]</code> ― 三次元配列 | ||
+ | * <code>array[str]</code> ― 連想配列 | ||
+ | ** <code>for (x in array) { ... }</code> ですべてのキーを取り出し可能 | ||
+ | ** <code>if (str in array) { ... }</code> でキー str があるかどうか | ||
+ | ** <code>array[str] = array[str] "hoge"</code> で連結可能 | ||
+ | |||
+ | === 関数 === | ||
+ | 関数定義は function で行う。ローカル変数は以下のように引き数とはスペースで少し離して記載する。 | ||
+ | function name (param1, param2, local) { | ||
+ | body-of-function | ||
+ | } | ||
+ | |||
+ | * 配列は参照渡しになる (関数の中で書き換え可能) | ||
+ | * sub 系の関数の返り値は置換した個数。渡した文字列が in-place で置換されるので注意。 | ||
+ | |||
+ | === 文字列 === | ||
+ | |||
+ | * 文字列を単に並べると連結 "hoge" "fuga" → "hogefuga" | ||
+ | * <code>print $1, $2</code> でスペース空けて出力 (区切りは OFS で変更可) | ||
+ | |||
+ | === その他 === | ||
+ | * 変数の初期化は不要 | ||
+ | * <code>{ print $0 } = { print } = </code> | ||
+ | ** 要するに、<code>grep hoge = awk /hoge/</code> | ||
+ | * $n (n > 0) を書き換えると、$0 も書き換わる | ||
+ | * $(n) で入力レコードを変数で指定できる。 | ||
+ | つまり、以下のように for で回すことが可能。 | ||
+ | for (i = 1; i <= NF; i++) { | ||
+ | print $(i) | ||
+ | } | ||
== サンプルスクリプト == | == サンプルスクリプト == | ||
行38: | 行73: | ||
ソースや出力結果などは通常これを用いる。 | ソースや出力結果などは通常これを用いる。 | ||
− | いちいち手作業で空白を入れるのは面倒なので (vim で C-v I | + | いちいち手作業で空白を入れるのは面倒なので (vim で C-v I はまあ許せるとして) |
− | + | gawk スクリプトにする。これはお手軽。 | |
− | [hagio@localhost hagi_utils]$ cat addspace.gawk | addspace.gawk | + | [hagio@localhost hagi_utils]$ cat addspace.gawk | ./addspace.gawk |
− | + | #!/bin/gawk -f | |
− | + | { | |
− | + | print " " $0 | |
− | + | } | |
ただ、コマンド行はスペースが入らないので注意すること。>自分 | ただ、コマンド行はスペースが入らないので注意すること。>自分 | ||
+ | |||
+ | === レコード範囲指定 === | ||
+ | begin を含む行から end を含む行の範囲だけを出力する場合は、以下のように sed と同じように指定する。 | ||
+ | $ awk '/begin/,/end/' data | ||
+ | では、その範囲だけ出力しない場合は?これは、next を使う。 | ||
+ | $ awk '/begin/,/end/{next} 1' data | ||
+ | 最後の 1 が最短の秘訣 ;-) |
2011年3月10日 (木) 00:47時点における最新版
手軽さとパワーのバランスが素晴らしい AWK について。
ちなみに、AWK の A は、(オレの好きな) かの有名な Aho-Corasick 法を作った Aho 氏の A である!K はカーニハン。そりゃいい言語だわな。
目次
参考文献
- The GNU Awk User's Guide (3.1.6) — 本家のマニュアル
- The GAWK Manual (2.15.6)
- AWK Language Programming (3.0.4)
覚え書き
コマンド構文
awk [-F sep] [-f progfile] [-v name=value] 'program' [file ...]
- セパレータ (デリミタ) は -F で指定することに注意
- -f で自作ライブラリを複数取り込める
- -v で変数を渡す
組み込み変数
- FS ― フィールドセパレータ (デフォルトはスペース)
- NR ― 現レコード数
- NF ― フィールド数
- OFS ― 出力フィールドセパレータ (print のカンマ区切りのセパレータ; デフォルトはスペース)
- ORS ― 出力レコードセパレータ (デフォルトは改行)
演算子
- ~ ― 正規表現にマッチしたら真 ($0 ~ /re/)
他はほぼ C と同じ
制御構文
-
break
,continue
― for や while の中で使う -
next
― 次のレコードへ処理を移す -
exit
― 残りのレコードは見ないで処理を中断 (END の中は実行されるので注意)
配列
-
array[i]
― 一次元配列 -
array[i,j,k]
― 三次元配列 -
array[str]
― 連想配列-
for (x in array) { ... }
ですべてのキーを取り出し可能 -
if (str in array) { ... }
でキー str があるかどうか -
array[str] = array[str] "hoge"
で連結可能
-
関数
関数定義は function で行う。ローカル変数は以下のように引き数とはスペースで少し離して記載する。
function name (param1, param2, local) { body-of-function }
- 配列は参照渡しになる (関数の中で書き換え可能)
- sub 系の関数の返り値は置換した個数。渡した文字列が in-place で置換されるので注意。
文字列
- 文字列を単に並べると連結 "hoge" "fuga" → "hogefuga"
-
print $1, $2
でスペース空けて出力 (区切りは OFS で変更可)
その他
- 変数の初期化は不要
-
{ print $0 } = { print } =
- 要するに、
grep hoge = awk /hoge/
- 要するに、
- $n (n > 0) を書き換えると、$0 も書き換わる
- $(n) で入力レコードを変数で指定できる。
つまり、以下のように for で回すことが可能。
for (i = 1; i <= NF; i++) { print $(i) }
サンプルスクリプト
Wiki 用に空白を挿入する
Wiki では、行が空白から始まっていると、以下のように固定幅フォントでタイプした通りに表示される。
ソースや出力結果などは通常これを用いる。
いちいち手作業で空白を入れるのは面倒なので (vim で C-v I はまあ許せるとして) gawk スクリプトにする。これはお手軽。
[hagio@localhost hagi_utils]$ cat addspace.gawk | ./addspace.gawk #!/bin/gawk -f { print " " $0 }
ただ、コマンド行はスペースが入らないので注意すること。>自分
レコード範囲指定
begin を含む行から end を含む行の範囲だけを出力する場合は、以下のように sed と同じように指定する。
$ awk '/begin/,/end/' data
では、その範囲だけ出力しない場合は?これは、next を使う。
$ awk '/begin/,/end/{next} 1' data
最後の 1 が最短の秘訣 ;-)