【yqコマンド活用】yqコマンドでYAMLファイルを自由自在に操作する


※ 当ページには【広告/PR】を含む場合があります。
2023/06/09
蛸壺の技術ブログ|yqコマンドでYAMLファイルを自由自在に操作する



アプリケーションの初期化ファイル・設定ファイルとして、
「YAML」 形式を採用することがかなり浸透してきました。
個人的に、比較される「JSON」形式の設定ファイルをYAML形式に置き換える大きなアドバンテージに、
「コメントを簡単に挿入することができる」 という点が大きく感じます。
とはいえ、YAML形式でもJSON形式でも、何百行も長々と設定を手で書き込んでいくのはとてもしんどい作業です。
ここではシェルスクリプトから「YAML」形式のファイルの自動生成化に便利な
『yq』 を導入するやり方を紹介します。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

yqをLinuxにインストール



そもそも、「yq」はJSON向けの高機能パーサーコマンドである「jq」を模して開発されているコマンドアプリケーションです。
jqについてはこのブログでも時々、ちょっとした特集を組んで記事として上げているので興味があればそちらをご覧ください。

合同会社タコスキングダム|蛸壺の技術ブログ
Alpine LinuxのDockerコンテナ内で使うjqをインストールする方法

LinuxでJSONファイルを操作する場合にシェルスクリプトで手軽に使えるjqコマンドをDocker上のalpine linuxコンテナへ導入してみます。



現在、yqコマンドはLinuxに限らず、幅広いOSの種類をサポートしています。
yqの各OSへのインストール方法は
公式のドキュメント に紹介してある通りです。
ここでは、手元のDebian OSでyqを導入して動作確認をしますが、LinuxOSであればパッケージインストーラ
『snap』 を使っているので、インストールの手順はほとんど一緒です。
各Linuxへのsnapのインストールに関する注意点として、
こちらのブログ にも言及されているように、

            $ sudo apt install snap
$ snap --version
snap: コマンドが見つかりません

        

という感じで、snapコマンドが実行されません。
snapプログラムは、本体である
『snapd』という常駐デーモン のユーティリティプログラムの一つで、Debianの場合以下のようにすると、併せてsnapコマンドも導入することができます。

            $ sudo apt install snapd
$ snap --version
snap    2.49-1+deb11u2
snapd   2.49-1+deb11u2
series  16
debian  11
kernel  5.10.0-21-amd64

        

無事にsnapコマンドが使えるようになったらyqの導入は一発です。

            $ snap install yq
2023-06-08T18:13:22+09:00 INFO Waiting for automatic snapd restart...
Warning: /snap/bin was not found in your $PATH. If you've not restarted your
         session since you installed snapd, try doing that. Please see
         https://forum.snapcraft.io/t/9469 for more details.

yq v4.34.1 from Mike Farah (mikefarah) installed

        

なお、snapからのパッケージインストール直前にはrootのパスワードを要求されます。
そのまますんなりとyqがインストールできればよかったのですが、何やら
/snap/bin のパスが環境変数に通っていない、という警告が出てきています。
こういう警告が出てしまった場合には、いくつか対処法がありますが、Debian OS系の場合の定石的な処置として、
.bashrc/snap/bin を登録しましょう。

            $ echo 'export PATH=$PATH:/snap/bin' >> ~/.bashrc
$ source ~/.bashrc

        

正常にパスが通ると、yqが利用可能な状態となっています。

            $ yq --version
yq (https://github.com/mikefarah/yq/) version v4.34.1

        

合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

yqを簡単に使ってみよう



先程の説の内容で、yqをLinuxに導入しました。
せっかくですので、準備運動的な使い方を試してみましょう。
ちなみに、現行の
『yq v4』 系からは、本家jqをより意識した用法に変わっています。
断りがなければ、v4ベースの利用方法で説明していますので、v3以前の構文には触れていませんのでご了承ください。


参照|yq公式ドキュメンテーション

yqの基本



yqはjqを意識されて作られています。
例えば、以下のようなyamlファイルがあるとしましょう。

            whoami: HOGE

        

この
whoami キーの値を取得する場合、以下のように書けます。

            $ file=$(cat << EOF
whoami: HOGE
EOF
)
$ echo "$file" | yq .whoami
HOGE

        

jqと同じように、
. がルートのオブジェクトへの参照とみなすことができて、そこから whoami フィールドにアクセスしているという意味になります。

yqでのフィールドの書き換え



もう少し応用してみましょう。
例えば特定のフィールドの値を書き換えたい場合には、先程の例を少し発展させてみましょう。

            $file=$(cat << EOF
whoami: HOGE
EOF
)
$ echo "$file" | yq '
    .whoami = "PIYO" | .
'
whoami: PIYO

        

ちゃんと
.whoami に値が代入できて、フィールドに反映されていることがわかります。

環境変数を利用する



yqの組み込み関数
strenv を使うと、環境変数から値を取得し使うことが可能です。

            #👇環境変数をセット
$ export HOGE_VAR=SECRET_HOGE
$ file=$(cat << EOF
whoami: HOGE
EOF
)
$ echo "$file" | yq '
    .whoami = strenv(HOGE_VAR) | .
'
whoami: SECRET_HOGE

        

これも使いどころによっては便利です。

複数のフィールドを書き換える



もう少し深い階層構造になっているyamlを操作してみましょう。

            title: 僕のお家
family:
  -
    member: 
    age: 13
    favorite: ハンバーグ
  -
    member: おやじ
    age: 43
    favorite: 
  -
    member: ママ
    age: 45
    favorite: パチンコ
  -
    member: たま
    age: 2
    favorite: マタタビ

        

まず一つのフィールドを換えてみましょう。

            $ file=$(cat << EOF
title: 僕のお家
family:
  -
    member: 僕
    age: 13
    favorite: ハンバーグ
  -
    member: おやじ
    age: 43
    favorite: 酒
  -
    member: ママ
    age: 45
    favorite: パチンコ
  -
    member: たま
    age: 2
    favorite: マタタビ
EOF
)
$ echo "$file" | yq '
    .family[1].favorite = "ゴルフ" | .
'
#👇出力
title: 僕のお家
family:
  - member: 僕
    age: 13
    favorite: ハンバーグ
  - member: おやじ
    age: 43
    favorite: ゴルフ
  - member: ママ
    age: 45
    favorite: パチンコ
  - member: たま
    age: 2
    favorite: マタタビ

        

ターゲットのフィールド値だけ置き換わっていることがわかります。
さらに同時に複数のフィールドを変更したい場合には、
| でパイプすることもできます。

            $ echo "$file" | yq '
    .title = "山田家" |
    .family[1].favorite = "ゴルフ" |
    .family[0].member = "のりお" |
    .family[0].health = "健康" |
    .family[4].member = "ぽち" |
    .
'
#👇出力
title: 山田家
family:
  - member: のりお
    age: 13
    favorite: ハンバーグ
    health: 健康
  - member: おやじ
    age: 43
    favorite: ゴルフ
  - member: ママ
    age: 45
    favorite: パチンコ
  - member: たま
    age: 2
    favorite: マタタビ
  - member: ぽち

        

まだまだyqで使える構文のほんのちょっとしかお見せできていませんが、さらなる構文の紹介はまた別の機会にでも特集します。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集

まとめ



ということで、簡単な「yq」の導入と使い道に触れてみました。
まだこれだと、yqの底しれぬ実力の一部しか紹介していませんので、他の強力な機能はまた後日ブログ記事にしてみようかと思います。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。

合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】シェルスクリプトをこれから学びたい人のためのオススメ書籍&教材特集