yqの使い方完全ガイド【インストールから応用まで】
システムの設定ファイルやアプリケーションのデータを扱う際、YAMLやJSON形式を目にする機会は少なくありません。Kubernetesのマニフェスト、Docker Composeの設定、各種ツールの設定ファイルなど、これらは日々私たちの開発や運用を支えています。
これらのファイルを編集する際、手作業で修正するのは非常に手間がかかります。特定の値を検索し、書き換え、あるいは複数のファイルから必要な情報だけを抽出する。こうした作業は、ヒューマンエラーの温床にもなりがちです。
もし、これらの煩雑な作業をコマンド一つで自動化できたらどうでしょうか。特定のキーの値を瞬時に取得し、必要な部分だけを安全に更新する。複数の設定ファイルから、特定の条件に合致するデータだけをまとめて取り出す。
yqは、まさにそのような願いを叶える強力なCLIツールです。複雑な設定ファイルの操作を、まるでデータベースを操作するかのように簡単にしてくれます。これにより、手動での作業時間が大幅に削減され、ミスのリスクも減らせます。開発や運用における設定ファイルとの付き合い方が、劇的に変わるでしょう。
yqとは
yqは、YAML、JSON、XML、TOML、INI、CSV、TSV、Properties形式のデータをコマンドラインで処理するための軽量なツールです。jqという人気のJSON処理ツールに似た構文を持ち、多様なデータ形式に対応しています。
その誕生の背景には、設定ファイルの多様化があります。特にYAMLはKubernetesの設定などで広く使われています。しかし、YAMLファイルをコマンドラインで操作する標準的なツールは長く存在しませんでした。yqは、jqがJSONに対して提供する強力な操作性を、これらの形式にも提供するために開発されました。
Go言語で書かれており、依存関係のない単一のバイナリとして動作します。そのため、ダウンロードしてすぐに使える手軽さも魅力です。設定ファイルの読み取り、特定のキーの更新、データのフィルタリングなど、さまざまな操作をシンプルなコマンドで実行できます。
インストール方法
yqはGo言語で書かれているため、多くのプラットフォームで簡単にインストールできます。OSごとの主要なインストール方法を紹介します。
macOS
macOSでは、HomebrewまたはMacPortsを利用するのが最も手軽です。
Homebrewを使用する場合
brew install yq
MacPortsを使用する場合
sudo port install yq
Linux
Linuxでは、Snap、パッケージマネージャー、あるいはバイナリの直接ダウンロードが利用できます。
Snapを使用する場合
多くのLinuxディストリビューションで利用可能です。
sudo snap install yq
apt (Debian/Ubuntu) を使用する場合
sudo apt-get update
sudo apt-get install yq
yum (CentOS/RHEL) を使用する場合
sudo yum install yq
バイナリを直接ダウンロードする場合
GitHubのリリースから、ご自身のシステムに合ったバイナリをダウンロードし、PATHが通ったディレクトリに配置します。
# 例えばLinux 64bitの場合
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq
chmod +x /usr/local/bin/yq
Windows
Windowsでは、Scoop、Chocolatey、またはバイナリの直接ダウンロードが便利です。
Scoopを使用する場合
scoop install yq
Chocolateyを使用する場合
choco install yq
バイナリを直接ダウンロードする場合
GitHubのリリースから、yq_windows_amd64.exeのようなバイナリをダウンロードし、PATHが通ったディレクトリに配置します。
Dockerを使用する場合
Dockerがインストールされている環境であれば、イメージを使ってyqを実行できます。
docker run --rm -i -v "${PWD}:/work" mikefarah/yq '.key' < your_file.yaml
インストールが完了したら、yq --versionコマンドでバージョンが表示されるか確認しましょう。
yq --version
基本的な使い方
yqの基本的な操作は非常に直感的です。ここでは、最低限これだけ知れば使えるコマンドをいくつか紹介します。まず、以下のconfig.yamlファイルを例として使用します。
# config.yaml
metadata:
name: my-app
version: "1.0.0"
database:
host: localhost
port: 5432
user: admin
password: "password123"
services:
- name: frontend
port: 80
- name: backend
port: 8080
1. 特定の値の読み取り
ドット(.)を使って、オブジェクトのキーを辿り、特定の値を抽出します。配列の場合はインデックスを指定します。
# metadata.nameの値を読み取る
yq '.metadata.name' config.yaml
出力:
my-app
# サービスの最初の要素 (frontend) の名前を読み取る
yq '.services[0].name' config.yaml
出力:
frontend
2. 特定の値の設定・更新
=演算子を使って、指定したキーに新しい値を設定します。変更をファイルに直接書き込む場合は、-i (in-place) オプションを使用します。
# metadata.versionの値を"2.0.0"に更新する
yq -i '.metadata.version = "2.0.0"' config.yaml
config.yamlは以下のように変更されます。
metadata:
name: my-app
version: "2.0.0" # ここが変更された
# ...(以下略)
新しいキーを追加することも可能です。
# 新しいキー 'environment' を追加する
yq -i '.environment = "production"' config.yaml
3. パイプからの入力と出力形式の変更
yqはパイプを通じて標準入力からデータを受け取り、標準出力へ結果を出力できます。-oオプションで出力形式を指定することも可能です。
# config.yamlをパイプで渡し、データベースのホスト名を出力する
cat config.yaml | yq '.database.host'
出力:
localhost
# config.yamlを読み込み、JSON形式で出力する
yq -o json '.' config.yaml
出力:
{
"metadata": {
"name": "my-app",
"version": "2.0.0"
},
"database": {
"host": "localhost",
"port": 5432,
"user": "admin",
"password": "password123"
},
"services": [
{
"name": "frontend",
"port": 80
},
{
"name": "backend",
"port": 8080
}
],
"environment": "production"
}
4. コメントの操作
yqはコメントも扱えます。commentsキーワードを使って、キーにコメントを追加したり変更したりできます。
# metadata.nameキーにコメントを追加する
yq -i '(.metadata.name | key) comments = "アプリケーションの名前"' config.yaml
config.yamlは以下のように変更されます。
metadata:
name: my-app # アプリケーションの名前
version: "2.0.0"
# ...(以下略)
5. 配列への要素の追加
配列の末尾に新しい要素を追加するには、+=演算子を使います。
# services配列に新しいサービスを追加する
yq -i '.services += {"name": "admin-panel", "port": 3000}' config.yaml
config.yamlのservicesセクションは以下のように変更されます。
services:
- name: frontend
port: 80
- name: backend
port: 8080
- name: admin-panel # ここが追加された
port: 3000
これらの基本的なコマンドを組み合わせることで、多くの設定ファイル操作が可能です。
便利な使い方・応用例 3選
yqは、単に値を読み書きするだけでなく、複雑なデータ変換や自動化にも活用できます。ここでは、実際の開発シーンで役立つ応用例を3つ紹介します。
1. Kubernetesマニフェストの一括更新
Kubernetesのデプロイメントで、コンテナイメージのバージョンを一括で更新するシナリオを考えます。手動で複数のマニフェストファイルを修正するのは手間がかかります。
例えば、deployment.yamlというファイルがあり、その中のnginxコンテナのイメージバージョンを1.21.0から1.22.0に更新したいとします。
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.21.0 # このバージョンを更新したい
ports:
- containerPort: 80
- name: sidecar
image: busybox:1.34.0
yqを使えば、特定のコンテナ名を持つイメージだけを更新できます。
# nginxコンテナのイメージバージョンを1.22.0に更新
yq -i 'select(.kind == "Deployment") | .spec.template.spec.containers[] |= select(.name == "nginx").image = "nginx:1.22.0"' deployment.yaml
このコマンドは、以下の処理を実行します。
select(.kind == "Deployment"):kindがDeploymentであるドキュメントのみを選択します。.spec.template.spec.containers[]: コンテナの配列をイテレートします。|= select(.name == "nginx").image = "nginx:1.22.0":nameがnginxであるコンテナのimageフィールドをnginx:1.22.0に更新します。
これにより、deployment.yaml内のnginxイメージだけが更新され、他のコンテナやドキュメントには影響を与えません。複数のデプロイメントファイルがある場合でも、ワイルドカードでまとめて処理できます。
# 複数のdeployment-*.yamlファイルを一括で更新する場合
yq -i 'select(.kind == "Deployment") | .spec.template.spec.containers[] |= select(.name == "nginx").image = "nginx:1.22.0"' deployment-*.yaml
2. 環境変数を使った設定ファイルの動的生成
CI/CDパイプラインなどで、環境変数に基づいて設定ファイルの一部を動的に変更したい場合があります。例えば、データベースの接続情報を環境ごとに切り替えたいとします。
以下のdb-config.yamlファイルがあるとします。
# db-config.yaml
database:
host: default-host
port: 5432
user: default-user
本番環境ではDB_HOSTとDB_USERという環境変数を使って設定を上書きしたいとします。
# 環境変数を設定(例)
export DB_HOST="prod-db.example.com"
export DB_USER="prod-admin"
# 環境変数を使ってdb-config.yamlを更新する
yq -i '.database.host = env(DB_HOST) | .database.user = env(DB_USER)' db-config.yaml
env(VARIABLE_NAME)構文を使うことで、指定した環境変数の値をyq式の中で利用できます。
db-config.yamlは以下のように変更されます。
database:
host: prod-db.example.com
port: 5432
user: prod-admin
これにより、環境ごとに異なる設定ファイルを生成する手間を省き、CI/CDパイプラインでの設定管理が柔軟になります。
3. 複数ファイルからの情報抽出とフィルタリング
複数の設定ファイルやログファイルから、特定の条件に合致するデータだけを抽出し、集約したい場合があります。
例えば、複数のservice-*.yamlファイルがあり、その中から特定のポートを持つサービスの名前だけを抽出したいとします。
# service-web.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
# service-api.yaml
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- protocol: TCP
port: 443
targetPort: 8443
# service-admin.yaml
apiVersion: v1
kind: Service
metadata:
name: admin-service
spec:
selector:
app: admin
ports:
- protocol: TCP
port: 80
targetPort: 3000
ポート80を持つサービスの名前をすべて抽出するには、-s (stream) オプションとselectフィルタを組み合わせます。
# ポート80を持つサービスの名前を抽出
yq -s 'select(.kind == "Service" and .spec.ports[].port == 80) | .metadata.name' service-*.yaml
出力:
web-service
admin-service
このコマンドは、以下の処理を実行します。
service-*.yaml: 複数のファイルをまとめてyqに渡します。-s: 複数のYAMLドキュメントをストリームとして処理します。select(...):kindがServiceであり、かつports配列のいずれかの要素がport: 80を持つドキュメントを選択します。.metadata.name: 選択されたドキュメントからmetadata.nameを抽出します。
この機能は、Kubernetesクラスター内のリソースの状態を把握したり、特定の条件を満たすサービスを一覧表示したりする際に非常に強力です。
他ツールとの組み合わせ
yqは単体でも強力ですが、他のCLIツールと組み合わせることで、その真価をさらに発揮します。パイプ(|)を通じて、さまざまなツールと連携できます。
1. jqとの連携
jqはJSONデータを扱う強力なツールです。yqでYAMLやXMLをJSONに変換し、その後jqでさらに複雑なJSON処理を行うことができます。
# YAMLファイルをJSONに変換し、jqでさらにフィルタリングする
yq -o json config.yaml | jq '.database | keys'
この例では、config.yamlをJSONに変換し、そのJSONデータからdatabaseオブジェクトのキー一覧をjqで取得しています。
出力:
[
"host",
"port",
"user",
"password"
]
2. grep, sed, awkとの連携
yqで抽出した値を、さらにテキスト処理ツールで加工できます。
# config.yamlから全てのサービス名を抽出し、"end"で終わるものだけをgrepでフィルタリングする
yq '.services[].name' config.yaml | grep 'end$'
出力:
frontend
backend
yqで構造化データから必要な情報を取得し、grepで特定のパターンを検索するといった使い方ができます。
3. シェルスクリプトでの自動化
yqはシェルスクリプトに組み込むことで、設定ファイルの自動生成、更新、検証などのタスクを自動化できます。
例えば、デプロイ時にバージョン情報を自動で更新するスクリプトを作成できます。
#!/bin/bash
# config.yamlから現在のバージョンを取得
CURRENT_VERSION=$(yq '.metadata.version' config.yaml)
echo "Current version: $CURRENT_VERSION"
# 新しいバージョンを生成 (例: メジャーバージョンをインクリメント)
NEW_VERSION=$(echo "$CURRENT_VERSION" | awk -F'.' '{print ($1+1)".0.0"}')
echo "New version: $NEW_VERSION"
# config.yamlのバージョンを更新
yq -i ".metadata.version = \"$NEW_VERSION\"" config.yaml
echo "Version updated to $NEW_VERSION"
このスクリプトを実行すると、config.yamlのmetadata.versionが自動的に更新されます。
4. gitとの連携
git diffで設定ファイルの変更をレビューする際、yqを使って特定の情報だけを比較することができます。例えば、パスワードのような機密情報を除外して差分を確認する際に役立ちます。
# config.yamlからパスワードを除外した内容を一時的に表示
yq 'del(.database.password)' config.yaml
このコマンドはパスワードを除外した内容を標準出力に出します。git diffのフィルタとして利用することは直接的には難しいですが、レビュー前に手動で確認する際に便利です。
よくある設定・カスタマイズ
yq自体には、dotfilesのような永続的な設定ファイルは存在しません。しかし、シェル機能や環境変数を活用することで、yqの挙動をカスタマイズしたり、よく使うコマンドを簡略化したりできます。
1. シェルのエイリアス設定
よく使うyqコマンドを、短縮されたエイリアスとしてシェルに登録することで、入力の手間を省けます。
例えば、yqでJSON形式の出力を頻繁に使う場合、以下のエイリアスを設定できます。
# .bashrc または .zshrc などに追記
alias yqj="yq -o json"
alias yqt="yq -o yaml" # 明示的にYAML出力したい場合
これで、yqj .key file.yamlと入力するだけで、JSON形式の出力を得られます。
Kubernetesのマニフェストから特定の情報を取得するコマンドが長い場合も、エイリアスが役立ちます。
# 特定のKubernetesリソースのnameとimageを抽出するエイリアス
alias yqk8s_img="yq '.items[] | select(.kind == \"Deployment\" or .kind == \"StatefulSet\") | .metadata.name + \": \" + .spec.template.spec.containers[0].image'"
2. 環境変数による挙動変更
yqはいくつかの環境変数を通じて、その挙動を制御できます。
YQ_COLOR_OUTPUT
出力の色付けを制御します。trueに設定するとカラー出力が有効になります。
# カラフルな出力にする
export YQ_COLOR_OUTPUT=true
yq '.' config.yaml
YQ_YAML_INDENT
YAML出力時のインデントスペース数を設定します。デフォルトは2です。
# インデントを4スペースにする
export YQ_YAML_INDENT=4
yq '.' config.yaml
これらの環境変数は、~/.bashrcや~/.zshrcなどのシェル設定ファイルに記述しておくことで、永続的に適用できます。
3. シェルスクリプトでの抽象化
複雑なyqの操作は、シェルスクリプトにまとめてファイルとして保存することで、再利用性を高められます。これは、事実上のカスタマイズ設定ファイルのようなものです。
例えば、特定のキーの値を安全に更新するスクリプトを作成します。
#!/bin/bash
# usage: update_config.sh <file> <key> <value>
FILE=$1
KEY=$2
VALUE=$3
if [ -z "$FILE" ] || [ -z "$KEY" ] || [ -z "$VALUE" ]; then
echo "Usage: $0 <file> <key> <value>"
exit 1
fi
echo "Updating $FILE: $KEY = $VALUE"
yq -i ".$KEY = \"$VALUE\"" "$FILE"
echo "Update complete."
このスクリプトをupdate_config.shとして保存し、実行権限を与えます。
chmod +x update_config.sh
./update_config.sh config.yaml database.host "new-prod-db"
このように、yq自体に設定ファイルがなくても、シェルの機能を活用することで、十分にカスタマイズされた開発環境を構築できます。
今日からできる実行プラン
yqの導入は非常に簡単です。以下の3ステップで、今日からyqを使い始めましょう。
ステップ1: yqをインストールする
まずは、ご自身のOSに合った方法でyqをインストールします。macOSならHomebrew、WindowsならScoop、LinuxならSnapが手軽です。
# 例: macOSの場合
brew install yq
インストール後、yq --versionコマンドで正しくインストールされたか確認してください。
ステップ2: 手元の設定ファイルで読み取りを試す
次に、普段使っているYAMLやJSON形式の設定ファイルを一つ選び、その内容をyqで読み取ってみましょう。簡単なパスから試すのがおすすめです。
例えば、sample.yamlというファイルがある場合。
# sample.yaml
app:
name: MyAwesomeApp
version: 1.0
# アプリケーション名を読み取る
yq '.app.name' sample.yaml
# バージョンを読み取る
yq '.app.version' sample.yaml
配列がある場合は、インデックスを指定して読み取ってみましょう。
ステップ3: 値の更新を試す
読み取りに慣れたら、次は値の更新に挑戦します。まずは、yq -iオプションを使わずに標準出力で結果を確認し、意図通りの変更になるか確かめましょう。
# バージョンを2.0に更新する(ファイルは変更されない)
yq '.app.version = 2.0' sample.yaml
出力された内容が正しければ、-iオプションを付けてファイルに直接変更を書き込みます。
# バージョンを2.0に更新する(ファイルに直接変更を書き込む)
yq -i '.app.version = 2.0' sample.yaml
これらのステップを通じて、yqの基本的な操作に慣れることができます。日々の開発や運用の中で、手作業で設定ファイルを修正する場面に遭遇したら、ぜひyqで自動化できないか検討してみてください。小さな自動化の積み重ねが、大きな効率化へと繋がります。