Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • shell

  • tool

    • mac 百问记录
    • mac tool
    • tmux
    • c tool
    • platform
    • dev tool
    • java tool
    • IDEA
    • vscode
    • Docker 使用指南
    • unbuntuOnWindows
    • oh-my-zsh
    • github
    • lldb
    • ripgrep 高性能文本搜索工具使用指南
    • appium
    • mvn
    • ffmpeg
    • gradle
    • git 使用指南
    • jenv
    • php-fpm
    • raycast
    • VisiData 终极生存指南(vd)
    • yq
      • 基础读取
      • 输出格式控制
      • 修改与写入
        • 赋值操作
        • 基于旧值计算
        • 多字段同时修改
      • 数组操作
        • 遍历与过滤
        • 映射与转换
        • 排序与去重
      • 多文件操作
        • 合并文件
        • 对比与引用
      • 注释与高级特性
      • 实战场景
        • Kubernetes 配置批量处理
        • 配置文件转换
        • CI/CD 中动态修改
      • 与 jq 的区别
      • 常用技巧
      • 常见问题
      • 链接
    • direnv
    • Vim 编辑器入门指南
    • jadx
    • excalidraw 入门指南
    • whimsical 入门指南
    • mermaid 入门指南
  • client

  • 网络

  • compute_base

  • blog

  • growth

  • java

  • C&C++

  • ai

  • secure

  • cms

  • english

  • 生活

  • 金融学

  • more

  • other
  • tool
Jacky
2026-08-30
目录

yq

# yq 实用指南

命令行里的 YAML/JSON/XML 处理器,语法对标 jq,专为配置文件读写、批量修改、格式转换而生。

本文档基于 mikefarah/yq v4(Go 版,目前主流)。Python 版 kislyuk/yq 是 jq 包装器,语法不同,请注意区分。

安装:brew install yq,验证 yq --version。


# 基础读取

yq '.' file.yaml                       # 读取整个文件(格式化输出)
yq '.metadata.name' deploy.yaml        # 读取嵌套字段
yq '.spec.replicas' deploy.yaml        # 读取数值
yq '.spec.template.containers[0].name' deploy.yaml  # 数组下标访问
yq '.spec.containers[].name' deploy.yaml             # 遍历数组,逐个输出
yq '.spec.containers[0].ports[].containerPort' deploy.yaml  # 嵌套数组展开
1
2
3
4
5
6

带路径前缀输出(方便知道值来自哪):

yq -o=props '.' file.yaml              # 输出 key=value 扁平格式
yq '... | style=""' file.yaml          # 递归遍历所有节点
1
2

读取时处理不存在的字段:

yq '.metadata.namespace // "default"' deploy.yaml   # 字段不存在时给默认值
1

# 输出格式控制

yq 支持多种输入输出格式,用 -P(输入)和 -o(输出)指定。

格式 输入 flag 输出 flag 说明
YAML 默认 默认 保留注释和顺序
JSON -P 或自动识别 -o=json 紧凑或美化
XML -P=xml -o=xml 支持属性
props -P=props -o=props Java properties 风格
csv / tsv 自动 -o=csv 数组转表格
# YAML 转 JSON(最常用)
yq -o=json '.' file.yaml
yq -o=json -I=2 '.' file.yaml         # JSON 缩进 2 空格

# JSON 转 YAML
yq -P '.' file.json                    # -P 表示输入是 JSON(也可自动识别)
yq '.' file.json                       # 多数版本自动识别输入格式

# 紧凑 JSON(单行)
yq -o=json -I=0 '.' file.yaml

# YAML 转 properties
yq -o=props '.' file.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13

颜色输出:默认终端着色,管道输出时自动关闭。强制着色 yq -C,关闭 yq -M。


# 修改与写入

# 赋值操作

# 修改字段值(输出到 stdout,不改变原文件)
yq '.spec.replicas = 5' deploy.yaml

# 原地修改文件(最常用)
yq -i '.spec.replicas = 5' deploy.yaml

# 新增字段
yq -i '.metadata.labels.env = "prod"' deploy.yaml

# 嵌套新增(中间路径自动创建)
yq -i '.spec.template.metadata.annotations."sidecar.istio.io/inject" = "true"' deploy.yaml

# 删除字段
yq -i 'del(.metadata.labels.temp)' deploy.yaml

# 删除数组元素
yq -i 'del(.spec.containers[1])' deploy.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 基于旧值计算

yq -i '.spec.replicas += 1' deploy.yaml          # 加 1
yq -i '.metadata.name = .metadata.name + "-canary"' deploy.yaml  # 字符串拼接
yq -i '.spec.replicas = .spec.replicas * 2' deploy.yaml          # 乘 2
1
2
3

# 多字段同时修改

yq -i '
  .metadata.labels.app = "nginx" |
  .spec.replicas = 3 |
  .spec.template.spec.containers[0].image = "nginx:1.25"
' deploy.yaml
1
2
3
4
5

用 | 连接多个操作,等价于顺序执行。


# 数组操作

# 遍历与过滤

# 遍历数组所有元素
yq '.items[]' list.yaml

# 过滤:选出 status=Running 的 Pod
yq '.items[] | select(.status.phase == "Running")' pods.yaml

# 过滤后只取名字
yq '.items[] | select(.status.phase == "Running") | .metadata.name' pods.yaml

# 多条件过滤
yq '.items[] | select(.status.phase == "Running" and .metadata.namespace == "default")' pods.yaml

# 过滤后保留数组结构(加括号)
yq '[.items[] | select(.status.phase == "Running")]' pods.yaml   # 输出仍是数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 映射与转换

# 从数组中提取字段组成新数组
yq '[.items[].metadata.name]' pods.yaml            # 输出 ["pod1","pod2",...]
yq -o=csv '.items[] | [.metadata.name, .status.phase]' pods.yaml  # 转 CSV

# 对每个元素做转换
yq '.spec.containers[] |= . + {resources: {limits: {cpu: "500m"}}}' deploy.yaml
1
2
3
4
5
6

# 排序与去重

yq '.items | sort_by(.metadata.name)' list.yaml     # 按名字排序
yq '.items | sort_by(.creationTimestamp) | reverse' list.yaml  # 按时间倒序
yq '.tags | unique' file.yaml                         # 数组去重
yq '.items | length' list.yaml                        # 数组长度
1
2
3
4

# 多文件操作

# 合并文件

yq 的合并用 * 操作符,支持不同合并策略。

# 基础合并:第二个文件覆盖第一个(同字段覆盖,不同字段保留)
yq '. * load("override.yaml")' base.yaml

# 深度合并(递归合并嵌套对象,数组默认替换)
yq '. *d load("override.yaml")' base.yaml            # *d = deep merge

# 数组合并(追加而非替换)
yq '. *+ load("extra.yaml")' base.yaml               # *+ = 数组追加

# 合并后输出到新文件
yq '. * load("prod.yaml")' base.yaml > merged.yaml
1
2
3
4
5
6
7
8
9
10
11

合并策略速查:

操作符 对象 数组 说明
* 覆盖 替换 默认
*d 深度合并 替换 递归合并嵌套
*+ 覆盖 追加 数组尾部追加
*d+ 深度合并 追加 最常用的"友好合并"

# 对比与引用

# 引用另一个文件的值进行赋值
yq -i '.spec.replicas = load("config.yaml").replicas' deploy.yaml

# 从文件读取字符串值
yq '.message = load_str("notes.txt")' file.yaml

# 多文件输入,按索引引用
yq 'select(fileIndex == 0)' a.yaml b.yaml            # 只处理第一个文件
yq 'select(fileIndex == 1) | .metadata.name' a.yaml b.yaml
1
2
3
4
5
6
7
8
9

# 注释与高级特性

yq v4 的核心优势是保留 YAML 注释和格式,这是 jq 做不到的。

# 读取注释
yq '.metadata headComment' file.yaml                  # 字段上方的注释
yq '.metadata lineComment' file.yaml                  # 行尾注释
yq '.metadata footComment' file.yaml                  # 字段下方注释

# 添加/修改注释
yq -i '.metadata headComment = "应用元数据"' file.yaml
yq -i '.spec.replicas lineComment = "副本数"' file.yaml

# 删除注释
yq -i '.metadata headComment = ""' file.yaml
1
2
3
4
5
6
7
8
9
10
11

锚点与别名:

yq 'explode(.)' file.yaml                              # 展开所有锚点引用(&/* → 实际值)
1

多行字符串样式控制:

yq '.description style="literal"' file.yaml            # 用 | 块样式
yq '.description style="folded"' file.yaml             # 用 > 折叠样式
yq '.description style=""' file.yaml                   # 自动选择
1
2
3

# 实战场景

# Kubernetes 配置批量处理

# 查看所有 Pod 名字和状态
kubectl get pods -o yaml | yq '.items[] | [.metadata.name, .status.phase] | @csv'

# 批量给所有 deployment 加标签
for f in deploy/*.yaml; do yq -i '.metadata.labels.managed-by = "argo"' "$f"; done

# 提取所有容器镜像
yq '[.. | select(has("image")) | .image] | unique' deploy.yaml

# 修改所有容器的镜像 tag
yq -i '(.spec.template.spec.containers[] | select(.name == "app").image) |= sub(":.*", ":v2.1.0")' deploy.yaml
1
2
3
4
5
6
7
8
9
10
11

# 配置文件转换

# Helm values 转 JSON 给其他工具用
yq -o=json '.' values.yaml > values.json

# JSON 转 YAML 并格式化
yq -P '.' config.json > config.yaml

# 提取嵌套配置为扁平 key=value
yq -o=props '.' application.yaml > application.properties
1
2
3
4
5
6
7
8

# CI/CD 中动态修改

# 用环境变量替换镜像 tag
yq -i ".spec.template.spec.containers[0].image = \"myapp:${TAG}\"" deploy.yaml

# 条件修改:只有 replicas > 3 时才设为 3
yq -i 'select(.spec.replicas > 3) | .spec.replicas = 3' deploy.yaml
1
2
3
4
5

# 与 jq 的区别

特性 yq jq
原生格式 YAML JSON
注释保留 支持 不支持
输出 YAML 原生 需额外工具
语法 类 jq,扩展了 YAML 特性 标准 jq
多格式输入输出 YAML/JSON/XML/CSV/props JSON
原地修改 -i 不支持(需重定向)

混用技巧:yq 转 JSON 后管道给 jq 做复杂计算,再转回 YAML:

yq -o=json '.' file.yaml | jq '.items | map(select(.price > 10))' | yq -P '.'
1

# 常用技巧

  • 不记得语法:yq --help 或 man yq,v4 文档在 https://mikefarah.gitbook.io/yq/
  • 预览不修改:去掉 -i,先看输出确认无误再加 -i 原地写
  • 复杂表达式写文件:yq -f script.yq file.yaml,把表达式存成文件避免 shell 转义噩梦
  • 调试表达式:yq -v 输出详细日志,或分步拆表达式确认每一步结果
  • 处理大文件:yq 一次性加载到内存,GB 级文件建议用 yq '.' 流式或换工具
  • shell 变量传入:用双引号包裹表达式,yq ".field = \"$VAR\"",或用 env(VAR) 函数:yq '.field = env(MY_VAR)' file.yaml

# 常见问题

  • Error: cannot index array with 'name':在数组上用了对象访问,先 [] 展开或加 [0]。
  • 修改后注释丢了:确认用的是 mikefarah/yq v4,Python 版 yq 不保留注释。
  • -i 不生效:v3 用 -y -i,v4 直接 -i;检查版本 yq --version。
  • 数字被改成字符串:赋值时不加引号 .replicas = 3 是数字,加引号 .replicas = "3" 是字符串。
  • 布尔值问题:YAML 中 true/false 是布尔,"true" 是字符串;yq 赋值时 .flag = true 保持布尔类型。
  • key 含特殊字符:用引号包裹 .metadata.annotations."app.kubernetes.io/name"。

# 链接

  • 官方文档 (opens new window)
  • GitHub 仓库 (opens new window)
  • 在线 Playground (opens new window)
#tool#Shell#yaml#json
上次更新: 2026/09/10, 14:32:04
VisiData 终极生存指南(vd)
direnv

← VisiData 终极生存指南(vd) direnv→

最近更新
01
direnv
09-09
02
nvim
09-09
03
wget
09-09
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式