📋

rfコマンドの実例: サーバ名とIPアドレスを抜き出す

に公開

実例: サーバ名とIPアドレスを抜き出す

最近便利だと感じたrfコマンドの実例を紹介します。
ファイルやコマンドの出力から特定の部分を抜き出したいときがあります。これが、スペースで区切られているならフィールドを指定するだけなので簡単ですが、そうではなく複雑な場合は少し面倒です。例えば、以下はOpenStackのCLIでサーバの一覧を出力した例です。

$ openstack server list --project foo
+--------------------------------------+--------------------+---------+--------------------------------------------------+--------------+--------+----------------------------------+
| ID                                   | Name               | Status  | Networks                                         | Image        | Flavor | Project ID                       |
+--------------------------------------+--------------------+---------+--------------------------------------------------+--------------+--------+----------------------------------+
| 57c2e178-094a-4179-a63e-4205dcce80f9 | api-172-16-0-171   | ACTIVE  | internal-1=172.16.0.171; internal-2=172.32.0.175 | ubuntu-22.04 | small  | e39e6d3cfc4347c6960325b078f81532 |
| c47085d8-626b-4dbb-8aa6-480a678c1bca | cache-172-16-1-195 | ACTIVE  | internal-1=172.16.1.195; internal-2=172.32.1.130 | ubuntu-24.04 | large  | e39e6d3cfc4347c6960325b078f81532 |
| 265105ae-4024-46df-9c2c-660913ab5ce4 | api-172-16-0-226   | SHUTOFF | internal-1=172.16.0.226; internal-2=172.32.1.107 | ubuntu-24.04 | large  | e39e6d3cfc4347c6960325b078f81532 |
| 8b8a83f1-9a1a-4d9a-823f-8065cd4b4585 | proxy-172-16-1-222 | ACTIVE  | internal-1=172.16.1.222; internal-2=172.32.1.219 | ubuntu-22.04 | small  | e39e6d3cfc4347c6960325b078f81532 |
| 4baab303-213e-4fce-822c-e8cea4510211 | proxy-172-16-1-33  | ACTIVE  | internal-1=172.16.1.33; internal-2=172.32.1.126  | ubuntu-24.04 | large  | e39e6d3cfc4347c6960325b078f81532 |
+--------------------------------------+--------------------+---------+--------------------------------------------------+--------------+--------+----------------------------------+

ここからサーバ名(Nameカラム)とinternal-1のIPアドレスを抜き出してみます。

$ openstack server list --project foo | rf 'm /(#{_4}).+((?&ipv4))/'
api-172-16-0-171 172.32.0.175
cache-172-16-1-195 172.32.1.130
api-172-16-0-226 172.32.1.107
proxy-172-16-1-222 172.32.1.219
proxy-172-16-1-33 172.32.1.126

意図した通り抜き出せました。この処理を行ったrfコマンドの内容について解説します。
まず、match(m)メソッドに正規表現を渡しています。これにより正規表現にマッチしたレコードがあると、MatchDataが生成されます。コマンドの評価結果としてMatchDataを返却すると、キャプチャグループを空白区切りで出力します。
つぎに正規表現を見てみます。前半の (#{_4})部分ですが、これは4番目のフィールドにマッチします。4番目のフィールドはサーバ名(Name)です。このName部分にマッチする正規表現を書くのは面倒なので、フィールドを埋め込むと簡潔に記述できることがあります。後半の((?&ipv))ですが、これはrfコマンドの独自拡張で (?&ipv4)部分をIPv4アドレスにマッチするパターンに内部的に置換しています。
これらの組み合わせにより、サーバ名(Name)とIPアドレスを抜き出しています。

GitHubで編集を提案

Discussion