jq 查找值为包含特定元素的数组的键
jq find keys whose value is an array containing a specific element
文件是
{
"ContentKey--4-0-47--Vovb1BQ": ["infra", "qa", "qa-ContentKey-4-0-47-Vovb1BQ", "internal-qa-Conten-WebServi-19E4PUWHRGD44-460820639.us-east-1.elb.amazonaws.com", "plan--default"],
"ContentKey--4-0-47--zjOkiQ": ["svc", "dev", "dev-ContentKey-4-0-47-zjOkiQ", "dev-Conte-WebServi-KXJXZBDY113W-2116785917.us-east-1.elb.amazonaws.com", "plan--default"],
"IdGenService--2001-4-22--CJUFaMQ": ["svc", "dev", "dev-IdGenService-2001-4-22-CJUFaMQ", "dev-IdGen-WebServi-R7RVXSYAV92W-304073075.us-east-1.elb.amazonaws.com"],
"IdGenService--2001-4-22--Uhf9CTQ": ["svc", "qa", "qa-IdGenService-2001-4-22-Uhf9CTQ", "internal-qa-IdGenS-WebServi-RT5BI5EEVZP3-665537643.us-east-1.elb.amazonaws.com"]
}
我想查找其数组值具有条目 svc
的键列表
我可以让下面的东西工作
cat list.json | jq '. | map(select (. | contains(["svc"])))'
但输出的是值数组而不是键本身
[
[
"svc",
"dev",
"dev-ContentKey-4-0-47-zjOkiQ",
"dev-Conte-WebServi-KXJXZBDY113W-2116785917.us-east-1.elb.amazonaws.com",
"plan--default"
],
[
"svc",
"dev",
"dev-IdGenService-2001-4-22-CJUFaMQ",
"dev-IdGen-WebServi-R7RVXSYAV92W-304073075.us-east-1.elb.amazonaws.com"
],
[
"svc",
"qa",
"qa-IdGenService-2001-4-22-Uhf9CTQ",
"internal-qa-IdGenS-WebServi-RT5BI5EEVZP3-665537643.us-east-1.elb.amazonaws.com"
]
]
你的json中的顶级对象是对象,不是数组。所以 .[]
只会产生它的值并丢弃键。使用 with_entries/1
过滤该对象。这会将对象转换为 key/value 对的数组,然后返回,您可以对其应用过滤器。
$ jq --arg key 'svc' 'with_entries(select(any(.value[]; . == $key)))' list.json
此外,您应该避免在此处使用 contains/1
。它以递归方式应用,因此它还将匹配包含子字符串 svc
的字符串。即,"Foosvcbar"
将被匹配。
根据您的输入,以下过滤器会产生如下所示的输出:
to_entries[] | select( .value | index("svc") ) | .key
输出:
"ContentKey--4-0-47--zjOkiQ"
"IdGenService--2001-4-22--CJUFaMQ"
"IdGenService--2001-4-22--Uhf9CTQ"
在这种情况下,使用 index/1
比使用 any/2
更简单而且(可能)更快。
文件是
{
"ContentKey--4-0-47--Vovb1BQ": ["infra", "qa", "qa-ContentKey-4-0-47-Vovb1BQ", "internal-qa-Conten-WebServi-19E4PUWHRGD44-460820639.us-east-1.elb.amazonaws.com", "plan--default"],
"ContentKey--4-0-47--zjOkiQ": ["svc", "dev", "dev-ContentKey-4-0-47-zjOkiQ", "dev-Conte-WebServi-KXJXZBDY113W-2116785917.us-east-1.elb.amazonaws.com", "plan--default"],
"IdGenService--2001-4-22--CJUFaMQ": ["svc", "dev", "dev-IdGenService-2001-4-22-CJUFaMQ", "dev-IdGen-WebServi-R7RVXSYAV92W-304073075.us-east-1.elb.amazonaws.com"],
"IdGenService--2001-4-22--Uhf9CTQ": ["svc", "qa", "qa-IdGenService-2001-4-22-Uhf9CTQ", "internal-qa-IdGenS-WebServi-RT5BI5EEVZP3-665537643.us-east-1.elb.amazonaws.com"]
}
我想查找其数组值具有条目 svc
我可以让下面的东西工作
cat list.json | jq '. | map(select (. | contains(["svc"])))'
但输出的是值数组而不是键本身
[
[
"svc",
"dev",
"dev-ContentKey-4-0-47-zjOkiQ",
"dev-Conte-WebServi-KXJXZBDY113W-2116785917.us-east-1.elb.amazonaws.com",
"plan--default"
],
[
"svc",
"dev",
"dev-IdGenService-2001-4-22-CJUFaMQ",
"dev-IdGen-WebServi-R7RVXSYAV92W-304073075.us-east-1.elb.amazonaws.com"
],
[
"svc",
"qa",
"qa-IdGenService-2001-4-22-Uhf9CTQ",
"internal-qa-IdGenS-WebServi-RT5BI5EEVZP3-665537643.us-east-1.elb.amazonaws.com"
]
]
你的json中的顶级对象是对象,不是数组。所以 .[]
只会产生它的值并丢弃键。使用 with_entries/1
过滤该对象。这会将对象转换为 key/value 对的数组,然后返回,您可以对其应用过滤器。
$ jq --arg key 'svc' 'with_entries(select(any(.value[]; . == $key)))' list.json
此外,您应该避免在此处使用 contains/1
。它以递归方式应用,因此它还将匹配包含子字符串 svc
的字符串。即,"Foosvcbar"
将被匹配。
根据您的输入,以下过滤器会产生如下所示的输出:
to_entries[] | select( .value | index("svc") ) | .key
输出:
"ContentKey--4-0-47--zjOkiQ"
"IdGenService--2001-4-22--CJUFaMQ"
"IdGenService--2001-4-22--Uhf9CTQ"
在这种情况下,使用 index/1
比使用 any/2
更简单而且(可能)更快。