jq入门者求助:如何按匹配规则将JSON数组跨文件添加
用jq实现跨JSON文件的数组匹配追加
嘿,作为jq初学者能想到用专门的JSON工具而不是sed/grep,这思路太赞了!完全可以用jq优雅解决你的需求,我一步步给你拆解清楚。
先明确场景(假设的JSON结构)
首先我先假设两个文件的结构,这样更容易理解命令逻辑——如果你的实际结构有差异,调整对应的字段名就行:
file_1.json 示例
[ { "id": "item1", "physical_endpoint": "https://hostname/api/v1", "url": [] }, { "id": "item2", "physical_endpoint": "http://hostname/service", "url": [] }, { "id": "item3", "physical_endpoint": "https://otherhost/test", "url": [] } ]
file_2.json 示例
[ { "endpoint": "https://hostname/api/v1", "url": ["https://hostname/api/v1/foo", "https://hostname/api/v1/bar"] }, { "endpoint": "http://hostname/service", "url": ["http://hostname/service/baz"] }, { "endpoint": "https://otherhost/test", "url": [] } ]
核心命令实现
我们的思路是:先把file_2的数据转成一个「endpoint -> url数组」的映射表(方便快速查找),然后遍历file_1的条目,筛选出符合前缀规则的条目,再把匹配到的url数组追加进去。
直接用这条命令:
jq --argfile file2 file_2.json ' # 把file2转成以endpoint为键的映射表,方便快速查找 ($file2 | INDEX(.endpoint)) as $endpoint_map # 遍历file1的每个条目 | map( # 筛选出以http[s]://hostname/开头的physical_endpoint if .physical_endpoint | test("^https?://hostname/") then # 追加匹配到的url数组,// [] 确保没匹配到的时候加空数组,避免null .url += $endpoint_map[.physical_endpoint].url // [] else # 不符合规则的条目保持原样 . end ) ' file_1.json
命令拆解解释
--argfile file2 file_2.json:把file_2.json的内容读入jq变量$file2,方便后续操作($file2 | INDEX(.endpoint)) as $endpoint_map:用jq内置的INDEX函数,把file2的数组转成一个对象,键是每个条目的endpoint值,值是整个条目——这样查找的时候直接用键值对,效率比遍历高很多map(...):遍历file1的每个数组元素,逐个处理test("^https?://hostname/"):用正则表达式匹配前缀,https?表示http或https,^确保是字符串开头.url += ...:把找到的url数组追加到原有的url数组后面// []:jq的「空值合并」操作符,如果找不到匹配的endpoint,就用空数组代替,避免出现null破坏JSON结构
保存结果
如果想把修改后的结果保存到新文件,直接重定向输出即可:
jq --argfile file2 file_2.json '...' file_1.json > updated_file_1.json
小调整:如果是模糊匹配?
如果你的「匹配项」不是完全相等,而是file2的endpoint包含file1的physical_endpoint,或者其他规则,只需要修改if条件里的判断逻辑就行。比如要匹配file2的endpoint以file1的physical_endpoint开头:
jq --argfile file2 file_2.json ' ($file2 | INDEX(.endpoint)) as $endpoint_map | map( if .physical_endpoint | test("^https?://hostname/") then .url += ($file2[] | select(.endpoint | startswith(.physical_endpoint)) | .url) // [] else . end ) ' file_1.json
内容的提问来源于stack exchange,提问作者Vicxtel0015
相关产品推荐
相关产品推荐

