如何获取YAML文件指定行的完整YAML路径?
用yq获取YAML行号对应的完整路径
核心思路
通过mikefarah/yq(v4.18+版本)遍历YAML的所有节点,结合节点的起始行号和结束行号,匹配目标行并返回最具体的路径(优先返回子节点路径,避免父节点的宽泛匹配)。
准备工作
确保安装mikefarah/yq v4.18+(该版本支持.end_line变量,可获取节点的结束行号)。
单行命令实现
针对目标行号,直接运行以下命令(以示例YAML文件example.yaml、目标行号4为例):
yq -r '.. | select(has("key")) | if (.line <=4 and .end_line >=4) then path | join(".") else empty end' example.yaml | head -n1
- 替换命令中的
4为你需要查询的行号(注意行号从0开始计数) - 替换
example.yaml为你的YAML文件路径
封装成脚本(更易用)
写一个bash脚本get_yaml_path.sh,方便重复使用:
#!/bin/bash if [ $# -ne 2 ]; then echo "用法: $0 <YAML文件路径> <目标行号(从0开始)>" exit 1 fi YAML_FILE="$1" TARGET_LINE="$2" yq -r '.. | select(has("key")) | if (.line <= '$TARGET_LINE' and .end_line >= '$TARGET_LINE') then path | join(".") else empty end' "$YAML_FILE" | head -n 1
给脚本加执行权限:
chmod +x get_yaml_path.sh
使用示例
- 查询第0行的路径:
./get_yaml_path.sh example.yaml 0→ 输出a - 查询第2行的路径:
./get_yaml_path.sh example.yaml 2→ 输出a.b.c - 查询第4行的路径:
./get_yaml_path.sh example.yaml 4→ 输出a.d
补充:Python实现(备选方案)
如果偏好Python,可以用ruamel.yaml库实现更灵活的逻辑:
- 安装依赖:
pip install ruamel.yaml - 保存以下代码为
get_yaml_path.py:
import sys from ruamel.yaml import YAML from ruamel.yaml.comments import CommentedMap, CommentedSeq yaml = YAML() yaml.preserve_quotes = True def find_path(node, target_line, current_path=""): if isinstance(node, CommentedMap): for key, value in node.items(): key_line = node.lc.key(key) end_line = node.lc.end_mark.line if key_line <= target_line <= end_line: new_path = f"{current_path}.{key}" if current_path else key child_path = find_path(value, target_line, new_path) return child_path if child_path else new_path elif isinstance(node, CommentedSeq): for idx, item in enumerate(node): item_line = node.lc.item(idx) end_line = node.lc.end_mark.line if item_line <= target_line <= end_line: new_path = f"{current_path}[{idx}]" if current_path else f"[{idx}]" child_path = find_path(item, target_line, new_path) return child_path if child_path else new_path return current_path if __name__ == "__main__": if len(sys.argv) != 3: print("用法: python get_yaml_path.py <yaml文件> <目标行号>") sys.exit(1) yaml_file = sys.argv[1] target_line = int(sys.argv[2]) with open(yaml_file, 'r') as f: data = yaml.load(f) print(find_path(data, target_line))
- 使用示例:
python get_yaml_path.py example.yaml 4→ 输出a.d
内容的提问来源于stack exchange,提问作者Julien Tanay
相关产品推荐
相关产品推荐

