我需要从一些JSON(使用jq
)一次删除多个键,并且我试图了解是否有更好的方法来执行此操作,而不是每次都调用map和del。这是我的输入数据:
test.json
[
{
"label": "US : USA : English",
"Country": "USA",
"region": "US",
"Language": "English",
"locale": "en",
"currency": "USD",
"number": "USD"
},
{
"label": "AU : Australia : English",
"Country": "Australia",
"region": "AU",
"Language": "English",
"locale": "en",
"currency": "AUD",
"number": "AUD"
},
{
"label": "CA : Canada : English",
"Country": "Canada",
"region": "CA",
"Language": "English",
"locale": "en",
"currency": "CAD",
"number": "CAD"
}
]
对于每个项目,我想删除数字,语言和国家/地区键。我可以用这个命令做到这一点:
$ cat test.json | jq 'map(del(.Country)) | map(del(.number)) | map(del(.Language))'
工作正常,我得到了所需的输出:
[
{
"label": "US : USA : English",
"region": "US",
"locale": "en",
"currency": "USD"
},
{
"label": "AU : Australia : English",
"region": "AU",
"locale": "en",
"currency": "AUD"
},
{
"label": "CA : Canada : English",
"region": "CA",
"locale": "en",
"currency": "CAD"
}
]
但是,我试图了解是否有jq
方法指定要删除的多个标签,因此我不必拥有多个map(del())
指令?
答案 0 :(得分:16)
您可以提供要删除的路径的流:
$ cat test.json | jq 'map(del(.Country, .number, .Language))'
另外,请注意,您可能更愿意将您想要的密钥列入白名单,而不是将特定密钥列入黑名单:
$ cat test.json | jq 'map({label, region, locale, currency})'
答案 1 :(得分:7)
无需同时使用map
和del
。
您可以将多个路径传递给del
,并用逗号分隔。
以下是使用“点式”路径符号的解决方案:
jq 'del( .[] .Country, .[] .number, .[] .Language )' test.json
.[]
,每个路径一次)这里是一个使用“数组样式”路径符号的示例,它使您可以将路径与通用前缀合并,如下所示:
jq 'del( .[] ["Country", "number", "Language"] )' test.json
.[]
)下合并子路径 peak的答案使用map
和delpaths
,尽管看来您也可以单独使用delpaths
:
jq '[.[] | delpaths( [["Country"], ["number"], ["Language"]] )]' test.json
总的来说,这里为了简洁起见,我会采用数组样式的表示法,但是知道做同一件事的多种方法总是很好的。
答案 2 :(得分:2)
delpaths
也值得了解,也许不那么神秘:
map( delpaths( [["Country"], ["number"], ["Language"]] ))
答案 3 :(得分:1)
除了@ user3899165的答案外,我发现还可以从“子对象”中删除键列表。
example.json
{
"a": {
"b": "hello",
"c": "world",
"d": "here's",
"e": "the"
},
"f": {
"g": "song",
"h": "that",
"i": "I'm",
"j": "singing"
}
}
$ jq 'del(.a["d", "e"])' example.json
答案 4 :(得分:1)
路易斯在其answer中提到的“数组样式”和“点样式”表示法之间有更好的折衷。
del(.[] | .Country, .number, .Language)
此表单还可用于从嵌套对象中删除键列表(请参阅russholio的answer):
del(.a | .d, .e)
暗示您还可以选择一个索引来删除以下项中的键:
del(.[1] | .Country, .number, .Language)
或多个:
del(.[2,3,4] | .Country,.number,.Language)
您可以使用range()
函数删除范围(切片符号不起作用):
del(.[range(2;5)] | .Country,.number,.Language) # same as targetting indices 2,3,4
一些注意事项:
map(del(.Country,.number,.Language))
# Is by definition equivalent to
[.[] | del(.Country,.number,.Language)]
如果键包含特殊字符或以数字开头,则需要用双引号将其引起来,例如:
."foo$"
,否则为.["foo$"]
。