amazon ec2 の現在の状態を API を利用して取得するスクリプトを作成している時に気がついた事です。
入力行に "running"、"stopping"、"stopped"、"pendding" のいずれかの単語が含まれる場合にその単語を抽出する処理ですが、 awk (1) の組み込み関数 sub()、gsub() ではマッチした部分の後方参照ができないのでマッチしたパターンに応じた変換を一度に行う事ができず、それぞれのパターンにマッチングさせて処理をするしかありません。
awk '
/^INSTANCE.*running/{
print running;
}
/^INSTANCE.*stopping/{
print stopping;
}
/^INSTANCE.*stopped/{
print stopped;
}
/^INSTANCE.*pending/{
print pending;
}
'
しかしこれではコードが冗長になってしまい解読性も悪くなり、あまりにも悲しいのでマニュアルをじっくりと調べた所、組み込み関数 match() で正規表現にマッチ処理を行うと、組み込み変数 RSTART にマッチした文字の位置、 RLENGTH にマッチした文字列の長さが設定されるので、組み込み関数 substr() と併用する事でマッチした部分を抽出する事ができる事に気がつきました。
awk '
/^INSTANCE/{
if(match($0, /running|stopping|stopped|pending/))
print substr($0, RSTART, RLENGTH);
if(match($0, /ec2.*\.amazonaws\.com/))
print substr($0, RSTART, RLENGTH);
}
'
awk (1) で正規表現によるパターン抽出を行う場合にちょっと便利な小技だと思います。
ちなみに gnu awk では組み込み関数 match() が拡張されていて、マッチした部分を簡単に取得する事ができる様ですが、POSIX 準拠の awk (1) の機能だけでも何とかマッチした部分を取得できる様になります。