Help us understand the problem. What is going on with this article?

awk による正規表現にマッチした部分の抜き出し

More than 5 years have passed since last update.

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) の機能だけでも何とかマッチした部分を取得できる様になります。

bsdhack
親バカがviでシェルスクリプトを書いてる様なヤツです。 古き良きUNIXが好きですが最近は Mac ばかり使ってます。 Unix/Linux 技術者をお捜しの方は是非声をかけて下さい
http://blog.bsdhack.org
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away