echo "apiVersion: v1
kind: Node
metadata:
name: host-cluster-control-plane-64j47
labels:
beta.kubernetes.io/arch: amd64
" | yq -o p
结果:
apiVersion = v1
kind = Node
metadata.name = host-cluster-control-plane-64j47
metadata.labels.beta.kubernetes.io/arch = amd64
这几乎就是我想要的。我正在寻找获得价值的关键。
我可以像这样使用
metadata.name
:
echo "apiVersion: v1
kind: Node
metadata:
name: host-cluster-control-plane-64j47
labels:
beta.kubernetes.io/arch: amd64
" | yq '.metadata.name'
但是如果需要,
-o p
的yq
选项不会引用密钥。
我不能使用
metadata.labels.beta.kubernetes.io/arch
作为键,因为正确的语法是 metadata.labels["beta.kubernetes.io/arch"]
.
是否有一种自动获取 yaml 文件密钥的方法,以便我可以在
yq
(或 jq
)中使用这些密钥?
期望的输出是这样的:
apiVersion = v1
kind = Node
metadata.name = host-cluster-control-plane-64j47
metadata.labels["beta.kubernetes.io/arch"] = amd64
我正在寻找有效的密钥,因为我想创建第二个命令行来选择这些值。
例如:
❯ k get nodes -o yaml | yq '.items[].metadata.labels["beta.kubernetes.io/arch"]'
amd64
amd64
amd64
您可以通过执行以下操作来接近:
yq '(.. | key | select(test("\."))) |= ("[\"" + . + "\"]")' file.yaml -op
apiVersion = v1
kind = Node
metadata.name = host-cluster-control-plane-64j47
metadata.labels.["beta.kubernetes.io/arch"] = amd64
或者你可以这样做:
yq '(.. | key | select(test("\."))) |= sub("\.", "\.")' file.yaml -op
apiVersion = v1
kind = Node
metadata.name = host-cluster-control-plane-64j47
metadata.labels.beta\\.kubernetes\\.io/arch = amd64
顺便说一句 - 我不确定它应该如何在属性文件中转义,我愿意更新 yq 以在本地完成它有人在 github 上提出了一个包含详细信息的错误...
免责声明:我写了yq
预先警告你试图滥用半生不熟的 yq -o=props 输出但它不会做你想要的,即使它被正确实现1 因为 JSONPath 使用
\.
来转义那些点,即使这可能是 kubectl-ism,因为该语法没有记录:
$ kubectl get no -o jsonpath='{.items[*].metadata.labels.beta\.kubernetes\.io/arch}'
amd64
可以对
annotations:
、labels:
、selector:
和您感兴趣的 kubernetes 对象中的其他自由格式键值对进行特殊处理,但可以肯定的是,它不会在一般情况下工作按照您想要的方式进行包装
对这里的
jq
表示歉意,我不知道如何在yq
中做到这一点,当然你可以使用你喜欢的任何占位符,我只知道制表符不能出现在kubernetes注释中,也标签
$ echo '
apiVersion: v1
kind: Node
metadata:
labels:
beta.kubernetes.io/arch: amd64
' | yq -o=json | jq '
.metadata.labels = (
[.metadata.labels|to_entries[]
| {key: .key|gsub("[.]";"\t"), value}
]
|from_entries)' | yq -o=p | sed -Ee 's@\\t@\\.@g'
apiVersion = v1
kind = Node
metadata.labels.beta\.kubernetes\.io/arch = amd64
fn 1: 其他人 提出了同样的问题,结果同样糟糕,我说“实施不正确”,因为
echo '{"alpha.beta":{"charlie":1}}' | yq -o=p | yq -p=p
没有往返
.
。我什至尝试偷偷摸摸地使用 beta\u002Ekubernetes
但似乎 unicode 转义处理发生在密钥词法分析之前,因此遭受相同的错误
意识到问题是
yq
,但是作为开箱即用的思维选项,可以使用python脚本打印密钥。基于Python 3
,使用Python模块argparse
和pyyaml
,使用pip3
安装
执行脚本:
python3 yaml_to_json.py <file>
脚本:yaml_to_json.py
import argparse
import yaml
def print_keys(data, prefix=""):
if isinstance(data, dict):
for key, value in data.items():
new_prefix = f"{prefix}.{key}" if prefix else key
if isinstance(value, dict):
print_keys(value, new_prefix)
elif isinstance(value, list):
for i, item in enumerate(value):
print_keys(item, f"{new_prefix}[{i}]")
else:
if "." in key:
print(f'{new_prefix}["{key}"] = {value}')
else:
print(f'{new_prefix} = {value}')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Print keys in a YAML file for JSONPath")
parser.add_argument("yaml_file", type=str, help="path to YAML file")
args = parser.parse_args()
with open(args.yaml_file, "r") as f:
data = yaml.safe_load(f)
for key, value in data.items():
if isinstance(value, dict):
for k, v in value.items():
if isinstance(v, dict):
for sub_k, sub_v in v.items():
new_key = f"{k}[\"{sub_k}\"]"
print(f"metadata.{new_key} = {sub_v}")
else:
new_key = f"metadata.{k}"
print(f"{new_key} = {v}")
else:
print(f"{key} = {value}")
说明: