我需要从一些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"
}
]
Run Code Online (Sandbox Code Playgroud)
对于每个项目,我想删除数字,语言和国家/地区键.我可以用这个命令做到这一点:
$ cat test.json | jq 'map(del(.Country)) | map(del(.number)) | map(del(.Language))'
Run Code Online (Sandbox Code Playgroud)
这很好,我得到了所需的输出:
[
{
"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"
}
]
Run Code Online (Sandbox Code Playgroud)
但是,我试图了解是否有jq方式指定要删除的多个标签,所以我不必有多个jq指令?
在此先感谢您的帮助!
小智 19
您可以提供要删除的路径流:
$ cat test.json | jq 'map(del(.Country, .number, .Language))'
Run Code Online (Sandbox Code Playgroud)
另外,请注意,您可能更愿意将您想要的密钥列入白名单,而不是将特定密钥列入黑名单:
$ cat test.json | jq 'map({label, region, locale, currency})'
Run Code Online (Sandbox Code Playgroud)
小智 13
这个问题在谷歌结果中的排名非常高,所以我想指出,在接下来的几年中,这个问题del显然已经被改变,这样你就可以删除多个键:
del(.key1, .key2, ...)
Run Code Online (Sandbox Code Playgroud)
因此,假设您的 jq 版本相当最新,就不要费尽心思去寻找语法解决方法。
Lou*_*dox 12
没有必要同时使用map和del。
You can pass multiple paths to del, separated by commas.
Here is a solution using "dot-style" path notation:
jq 'del( .[] .Country, .[] .number, .[] .Language )' test.json
Run Code Online (Sandbox Code Playgroud)
.[] once per path)Here is an example using "array-style" path notation, which allows you to combine paths with a common prefix like so:
jq 'del( .[] ["Country", "number", "Language"] )' test.json
Run Code Online (Sandbox Code Playgroud)
.[])peak's answer uses map and delpaths, though it seems you can also use delpaths on its own:
jq '[.[] | delpaths( [["Country"], ["number"], ["Language"]] )]' test.json
Run Code Online (Sandbox Code Playgroud)
Overall, here I'd go for the array-style notation for brevity, but it's always good to know multiple ways to do the same thing.
路易斯在他的回答中提到的“数组样式”和“点样式”符号之间更好的折衷。
del(.[] | .Country, .number, .Language)
Run Code Online (Sandbox Code Playgroud)
此表单还可用于从嵌套对象中删除键列表(请参阅 russholio 的回答):
del(.a | .d, .e)
Run Code Online (Sandbox Code Playgroud)
这意味着您还可以选择单个索引来从以下位置删除键:
del(.[1] | .Country, .number, .Language)
Run Code Online (Sandbox Code Playgroud)
或多个:
del(.[2,3,4] | .Country,.number,.Language)
Run Code Online (Sandbox Code Playgroud)
您可以使用该range()函数删除一个范围(切片符号不起作用):
del(.[range(2;5)] | .Country,.number,.Language) # same as targetting indices 2,3,4
Run Code Online (Sandbox Code Playgroud)
一些旁注:
map(del(.Country,.number,.Language))
# Is by definition equivalent to
[.[] | del(.Country,.number,.Language)]
Run Code Online (Sandbox Code Playgroud)
如果键包含特殊字符或以数字开头,则需要用双引号将其括起来,如下所示:
."foo$"或 else.["foo$"]。
delpaths也值得了解,而且也许不那么神秘:
map( delpaths( [["Country"], ["number"], ["Language"]] ))
Run Code Online (Sandbox Code Playgroud)
由于 的参数delpaths只是 JSON,因此此方法对于编程删除特别有用,例如,如果键名称可作为 JSON 字符串使用。
除了@user3899165 的回答之外,我发现要从“子对象”中删除键列表
example.json
{
"a": {
"b": "hello",
"c": "world",
"d": "here's",
"e": "the"
},
"f": {
"g": "song",
"h": "that",
"i": "I'm",
"j": "singing"
}
}
Run Code Online (Sandbox Code Playgroud)
$ jq 'del(.a["d", "e"])' example.json
| 归档时间: |
|
| 查看次数: |
10541 次 |
| 最近记录: |