使用jq如果value包含字符串“ null”,则需要删除特定的key:value对。该字符串可以是“ null”或“ null”。因此需要使用包含而不是完全匹配的字符串。如果不是字符串,它将是一个数字
我的示例json如下:(仅在'th'和'sf'键中应为空值)
'dets':{
'S1':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile1',
'th': -10,
'sf': 'null'
}
},
'S2':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile2',
'th': -5,
'sf': 3
}
},
'S3':{
'type':'bottom',
'input': [12,7,16],
'config':{
'file':'sfile3',
'th': ' null',
'sf': 'null '
}
}
}
所需的输出应类似于:
'dets':{
'S1':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile1',
'th': -10
}
},
'S2':{
'type':'class',
'input': [12,7,6,19],
'config':{
'file':'sfile2',
'th': -5,
'sf': 3
}
},
'S3':{
'type':'bottom',
'input': [12,7,16],
'config':{
'file':'sfile3'
}
}
}
我相信在del(。[] []。config.smoothing_span | select(contains(“ null”)))的线路上有些东西,但是由于类型不同,我遇到了问题。
答案 0 :(得分:1)
给定的数据不是有效的JSON,但是它是有效的HJSON,因此以下面向jq的解决方案的第一步是使用hjson将数据转换为JSON:
hjson -j input.hjson
应将什么值视为“ null”的概念可能会随时间而改变,因此在下面,让我们定义一个过滤器,该过滤器可用于捕获任何合适的定义,例如
def isnull: . == null or (type=="string" and test("null"));
(也许更好的定义是使用test("^ *null *$")
。)
isnull
的键,可以使用walk/1
:
walk(if type=="object"
then with_entries(select(.value|isnull|not))
else . end)
(如果您的jq没有步行,则可以简单地从https://github.com/stedolan/jq/blob/master/src/builtin.jq或网络上的其他位置复制并粘贴其定义。)
假设您的jq有walk
,我们可以这样写:
hjson -j input.hjson |
jq 'def isnull: . == null or (type=="string" and test("null"));
walk(if type=="object"
then with_entries(select(.value|isnull|not))
else . end)'
如果您希望更改的范围尽可能缩小,则可以使用map_values
,例如结合用于检查并可能删除特定键的辅助功能:
# key is assumed to be a filter, e.g. .foo
def delkey(key): if key | isnull then del(key) else . end;
.dets |= map_values(.config |= (delkey(.th) | delkey(.sf)))
如果要检查几个特定的键,则定义一个用于检查键列表的功能可能会更方便:
# keys is assumed to be an array of strings
def delkeys(keys):
with_entries(select(.key as $k
| (keys|index($k)) and (.value|isnull) | not));
.dets |= map_values(.config |= delkeys(["th", "sf"]))