咨询:用命令行提取Avro JSON Schema字段的名称、类型及默认值
命令行处理Avro Schema提取字段信息的解决方案
问题场景
给定以下Avro Schema JSON文件:
{ "type": "record", "name": "ShelfExPosition", "fields": [ { "name": "shopId", "type": { "type": "string", "avro.java.string": "String" }, "doc": "Id of the shop" }, { "name": "productId", "type": { "type": "string", "avro.java.string": "String" }, "doc": "Id of the product" }, { "name": "sourceId", "type": { "type": "string", "avro.java.string": "String" }, "doc": "Id of the source" }, { "name": "timestampTransmission", "type": "long", "doc": "Timestamp of the message" }, { "name": "productQuantity", "type": [ "null", "double" ], "doc": "Quantity of the product", "default": null } ] }
需要提取每个字段的名称、实际类型(忽略avro.java.string这类附加配置),以及存在时的默认值,预期输出格式如下:
"shopId" string "productId" string "sourceId" string "timestampTransmission" long "productQuantity" double null
之前尝试的jq命令无法正确解析嵌套类型、联合类型,也未提取默认值,实际输出不符合预期:
cat file.json | jq -r '.fields[] | "\"\(.name)\" : \(.type | tostring | sub("^(null)$"; "\\1 : null") | sub("(^\"|\"$)"; ""))"'
可行解决方案
使用以下jq命令即可实现需求:
jq -r '.fields[] | "\"\(.name)\"", (if .type | type == "object" then .type.type elif .type | type == "array" then .type[] | select(. != "null") else .type end), (if has("default") then .default else empty end) | @tsv' file.json | tr '\t' ' '
命令解析
- 遍历字段:
.fields[]逐个处理Schema中的每个字段对象 - 输出字段名:
"\"\(.name)\""生成带双引号的字段名称 - 解析实际类型:
- 若类型为嵌套对象(如
shopId的类型配置),取.type.type获取基础类型 - 若类型为联合类型数组(如
["null", "double"]),筛选掉"null"后取有效类型 - 其他情况直接使用
.type的值(如long)
- 若类型为嵌套对象(如
- 提取默认值:仅当字段包含
default属性时,输出该属性值,否则不输出 - 格式化输出:
@tsv将各部分用制表符分隔,再通过tr '\t' ' '替换为空格,匹配预期的空格分隔格式
执行该命令后,输出与预期完全一致。
内容的提问来源于stack exchange,提问作者user23581877
相关产品推荐
相关产品推荐

