如何将jq命令输出作为另一个jq命令参数过滤JSON文件
基于JSON内容过滤另一个JSON文件的问题与解决方法
问题场景
需通过data.json中的数据过滤accounts.json,操作步骤及遇到的问题如下:
- 从
data.json提取符合closeReason == "Fraud"条件的前10个客户ID,执行命令:
jq '[.data[] | select(.attributes.closeReason == "Fraud")][:10] | [.[].relationships.customer.id]' data.json
成功得到包含10个ID的JSON数组。
2. 尝试将上述ID数组作为参数传入jq命令过滤accounts.json,使用命令:
jq --argjson ids "$ARGS.positional[]" '.data[] | select(.id | IN($ids[]))' accounts.json
触发错误:jq: invalid JSON text passed to --argjson
示例JSON文件
data.json(提取客户ID的源文件)
[ { "type": "depositAccount", "id": "991231", "attributes": { "name": "William Heckerd", "status": "Closed", "closeReason": "Fraud", "fraudReason": "ACHActivity", "updatedAt": "2023-02-24T19:41:30.224Z" }, "relationships": { "customer": { "data": { "type": "customer", "id": "123456" } } } } ]
accounts.json(待过滤的目标文件)
{ "data": [ { "type": "individualCustomer", "id": "567898765", "attributes": { "createdAt": "2023-09-10T08:32:07.921Z", "fullName": { "first": "Foo", "last": "Example" }, "email": "theemail@gmail.com", "status": "Archived", "archiveReason": "FraudClientIdentified" } } ] }
解决方法
报错核心原因是--argjson要求传入完整合法的JSON字符串,而原命令中$ARGS.positional[]的传递方式不符合格式要求。以下两种方式可解决问题:
方式一:管道直接传递ID数组
无需单独保存ID数组,通过管道将第一个jq的输出直接作为第二个jq的参数输入:
jq '[.data[] | select(.attributes.closeReason == "Fraud")][:10] | [.[].relationships.customer.id]' data.json | jq --argjson ids - '.data[] | select(.id | IN($ids[]))' accounts.json
说明:--argjson ids -中的-表示从标准输入读取JSON数据,将其赋值给$ids变量。
方式二:先保存ID数组到变量,再传入命令
先将提取到的ID数组保存到Shell变量:
ids=$(jq '[.data[] | select(.attributes.closeReason == "Fraud")][:10] | [.[].relationships.customer.id]' data.json)
再将完整的JSON数组字符串传入jq命令:
jq --argjson ids "$ids" '.data[] | select(.id | IN($ids[]))' accounts.json
说明:直接将合法的JSON数组字符串传递给--argjson,确保参数格式符合要求。
内容的提问来源于stack exchange,提问作者Jose A
相关产品推荐
相关产品推荐

