本文介绍如何在 Python 中替代 jq '.cis[].properties.cloud_vm_display_name' | grep -v null 命令,从多个结构不一的 JSON 文件中稳健提取 cloud_vm_display_name 字段值,并规避语法错误与空值误判问题。
本文介绍如何在 python 中替代 `jq '.cis[].properties.cloud_vm_display_name' | grep -v null` 命令,从多个结构不一的 json 文件中稳健提取 `cloud_vm_display_name` 字段值,并规避语法错误与空值误判问题。
在 Shell 中用 jq 处理 JSON 非常便捷,但当需要集成到 Python 项目、批量处理多文件或进行更复杂的逻辑判断时,直接用 Python 原生解析更可控、可维护性更强。你遇到的 SyntaxError: invalid syntax(data1['cis'][][...])是因为 Python 不支持类似 jq 的通配符索引 [] —— 必须显式遍历列表。
✅ 正确做法:遍历 data1['cis'] 列表
假设已通过 json.load() 读取单个 JSON 文件为字典 data1,且其结构形如:
{
"cis": [
{
"properties": {
"cloud_vm_display_name": "azuXXXXX",
"TenantsUses": [ ... ]
}
},
{
"properties": {
"cloud_vm_display_name": "null",
...
}
}
]
}则应使用 安全遍历 + 显式空值检查,推荐以下写法:
# 方案 1:基础 for 循环(清晰易调试)
vm_names = []
for cis_item in data1.get('cis', []):
props = cis_item.get('properties', {})
name = props.get('cloud_vm_display_name')
# 注意:'null' 是字符串,不是 None;需区分 'null' 字面量 vs None/缺失值
if name is not None and name != 'null':
vm_names.append(name)
print(vm_names) # ['azuXXXXX', 'azuXXXXXX', ...]# 方案 2:简洁列表推导式(生产推荐)
vm_names = [
cis['properties']['cloud_vm_display_name']
for cis in data1.get('cis', [])
if cis.get('properties', {}).get('cloud_vm_display_name') not in (None, 'null')
]⚠️ 关键提醒:
Json Schema Toolkit下载使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
立即学习“Python免费学习笔记(深入)”;
- if not 'null' in name(原答案写法)存在严重逻辑缺陷:它会错误过滤掉 "anulled-server" 或 "nullified-db" 等合法名称;
- grep -v null 在 Shell 中实际匹配整行等于 "null" 的输出(因 jq 默认输出带引号字符串),但 Python 中应严格比对 == 'null' 或检查 is None;
- 更健壮的做法是使用 .get(key, default) 避免 KeyError,尤其当某些 cis 条目可能缺失 properties 或 cloud_vm_display_name 字段时。
? 批量处理多个 JSON 文件
若需处理目录下所有 *.json 文件(对应原始命令 cat * | jq ...),可结合 glob 和异常处理:
import json
import glob
all_vm_names = []
for filepath in glob.glob("*.json"):
try:
with open(filepath, encoding='utf-8') as f:
data = json.load(f)
# 对每个文件提取 names
names = [
cis.get('properties', {}).get('cloud_vm_display_name')
for cis in data.get('cis', [])
]
# 过滤掉 None 和字符串 'null'
valid_names = [n for n in names if n not in (None, 'null')]
all_vm_names.extend(valid_names)
except (json.JSONDecodeError, OSError) as e:
print(f"跳过无效文件 {filepath}: {e}")
print(all_vm_names)✅ 最佳实践总结
- ❌ 避免 if 'null' in name —— 语义错误,易误伤;
- ✅ 使用 name != 'null' and name is not None 或 name not in (None, 'null');
- ✅ 始终用 .get() 访问嵌套键,防止 KeyError;
- ✅ 批量处理时加入 try/except,保障程序鲁棒性;
- ✅ 若需完全复刻 jq '.cis[].properties.cloud_vm_display_name | values' 行为(自动跳过 null/undefined),Python 中等价逻辑即:仅保留非 None 且非 'null' 的字符串值。
掌握这种模式后,你不仅能替代 shell + jq 流水线,还能轻松扩展——例如添加去重、排序、写入 CSV 或对接监控系统,真正实现自动化运维闭环。


















