使用 jq 从 JSON 对象中删除键:值
Posted
技术标签:
【中文标题】使用 jq 从 JSON 对象中删除键:值【英文标题】:Remove a key:value from an JSON object using jq 【发布时间】:2018-01-30 19:21:25 【问题描述】:我正在尝试使用 jq 从 JSON 对象中添加和删除“键:值”。我是使用 jq 的新手,我不明白 jq 向我抛出的错误,因此非常感谢任何帮助我朝着正确方向前进的帮助。我的具体问题是我有一个 JSON 对象(如下),我希望能够从 JSON 对象中添加/删除“maxHeight”键/值。
我尝试了一些命令,但出现了错误……
jq 'recurse(.[]) |= del(.maxHeight)' new.json
无法遍历 null (null)
jq 'recurse(.[]) |= maxHeight' new.json
无法遍历字符串(“特征”)
jq 'recurse(.[]) |= .maxHeight' new.json
不能用字符串“style”索引字符串
new.json 文件看起来像这样...
"style":
"className": "feature",
"showLabels": false,
"color": "function(feature, variableName, glyphObject, track)if(feature.get(\"type\") === \"CDS\")return \"#9CFBF5\"; else if(feature.get(\"type\") === \"exon\")return \"#43A47F\"; else if(feature.get(\"type\") === \"intron\")return \"#E8E8E8\"; else if(feature.get(\"type\") === \"five_prime_UTR\")return \"#F192FE\"; else if(feature.get(\"type\") === \"three_prime_UTR\")return \"#FEC892\"; else return \"#FF0000\";",
"arrowheadClass": null,
"featureCss": "padding:3px;"
,
"menuTemplate": [
"label": "View details"
,
"label": "Highlight a gene"
,
"iconClass": "dijitIconBookmark",
"content": "function(track,feature,div) window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) ",
"action": "contentDialog",
"title": "(featurename)",
"label": "Create Note"
],
"hooks":
"modify": " function(track,feature,div) var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++)for(var j=0;j<checkArr.length;j++) if( i>3) if( feature[i] === checkArr[j] ) if(feature[i]==\"NonReference\")div.style.backgroundColor=\"red\"else if(feature[i]==\"Reference\")div.style.backgroundColor=\"green\"else if(feature[i]==\"Heterozygous\")div.style.backgroundColor=\"orange\"else if(feature[i]==\"Missing\")div.style.backgroundColor=\"grey\" "
,
"key": "cucumber_ChineseLong_v2.gff3",
"storeClass": "JBrowse/Store/SeqFeature/NCList",
"trackType": null,
"maxHeight": "200px",
"urlTemplate": "tracks/cucumber_ChineseLong_v2.gff3/refseq/trackData.json",
"compress": 0,
"label": "cucumber_ChineseLong_v2.gff3",
"type": "JBrowse/View/Track/CanvasFeatures"
【问题讨论】:
【参考方案1】:使用 jq-1.6,这会从输入中删除键 .maxHeight(如果它之前不存在,它甚至不会抱怨):
jq 'del(.maxHeight)' new.json
【讨论】:
你的意思是echo ' "a": 1, "b": 2 ' | jq 'del(.a)' >output.json
或echo ' "a": 1, "b": 2 ' >input.json; jq 'del(.a)' input.json >output.json
或echo ' "a": 1, "b": 2 ' >input.json; jq 'del(.a)' input.json | sponge input.json
与sponge
来自moreutils
【参考方案2】:
有两种方法:
有针对性的方法,在 Manipulating a JSON file with jqManipulating a JSON file with jq上一个问题的回答中说明了这一点
全局方法,忽略特定上下文。
以下说明了全局方法:
walk(if type == "object" and has("maxHeight") then del(.maxHeight) else . end)
这实际上是通过更新具有指定键的任何对象来“编辑”输入。
如果您的 jq 没有 walk/1
,只需在调用它之前包含其 def(例如来自 https://raw.githubusercontent.com/stedolan/jq/master/src/builtin.jq)。
【讨论】:
很抱歉问了一个愚蠢的问题,但是到底如何“在调用它之前包含它的 def”?我正在使用来自 bash 的 jq,不知道该把函数放在哪里 @Sebas 看到我的回答【参考方案3】:对于非常大的 JSON 文档,最好使用 jq 的“流解析器”来解决这类问题,至少在编辑操作大大减小文档大小的情况下。无论如何,这是一个使用 --stream
选项的解决方案:
jq --stream 'select(length == 2 and .[0][-1] == "maxHeight" | not)' new.json |
jq -n 'fromstream(inputs)'
请注意,-n
选项必须在第二次调用 jq 时使用。
【讨论】:
【参考方案4】:这是一个从 Electrum Wallet JSON 文件中删除几个密钥的示例,它在 zsh 和 bash 中使用 jq 版本进行了测试,没有内置 walk
:
jq -f <(
curl https://raw.githubusercontent.com/stedolan/jq/master/src/builtin.jq
echo 'walk('
for i in transactions spent_outpoints verified_tx3 txo txi addresses addr_history; do
echo 'if type == "object" and has("'"$i"'") then del(.'"$i"') else . end |'
done
echo '.)'
) ~/.electrum/testnet/wallets/default_wallet
【讨论】:
很酷,所以一开始就有 jq 文件就足够了【参考方案5】:我有类似的问题,但不想为此编写大量代码或花费太多时间。
我假设您解决了这个问题的原因。但对我来说,以下内容适用于我不必递归查找的值,即仅在顶层。另外,我不在乎是否存在空白/空值:
jq "if .maxHeight then .maxHeight = null else . end "
【讨论】:
以上是关于使用 jq 从 JSON 对象中删除键:值的主要内容,如果未能解决你的问题,请参考以下文章