Pet*_*e C 5 json stream-processing bigdata jq
在一个大型 json 文件中,我想从嵌套列表中删除一些元素,但保留文档的整体结构。
我的示例将其输入为(但真实的输入足够大以要求流式传输)。
{
"keep_untouched": {
"keep_this": [
"this",
"list"
]
},
"filter_this":
[
{"keep" : "true"},
{
"keep": "true",
"extra": "keeper"
} ,
{
"keep": "false",
"extra": "non-keeper"
}
]
}
Run Code Online (Sandbox Code Playgroud)
所需的输出仅删除了“filter_this”块的一个元素:
{
"keep_untouched": {
"keep_this": [
"this",
"list"
]
},
"filter_this":
[
{"keep" : "true"},
{
"keep": "true",
"extra": "keeper"
} ,
]
}
Run Code Online (Sandbox Code Playgroud)
处理此类情况的标准方法似乎是使用“truncate_stream”来重构流对象,然后再以通常的 jq 方式过滤这些对象。具体来说,命令:
jq -nc --stream 'fromstream(1|truncate_stream(inputs))'
Run Code Online (Sandbox Code Playgroud)
提供对对象流的访问:
{"keep_this":["this","list"]}
[{"keep":"true"},{"keep":"true","extra":"keeper"},
{"keep":"false","extra":"non-keeper"}]
Run Code Online (Sandbox Code Playgroud)
此时很容易过滤所需的对象。但是,这会从其父对象的上下文中剥离结果,这不是我想要的。
查看流式结构:
[["keep_untouched","keep_this",0],"this"]
[["keep_untouched","keep_this",1],"list"]
[["keep_untouched","keep_this",1]]
[["keep_untouched","keep_this"]]
[["filter_this",0,"keep"],"true"]
[["filter_this",0,"keep"]]
[["filter_this",1,"keep"],"true"]
[["filter_this",1,"extra"],"keeper"]
[["filter_this",1,"extra"]]
[["filter_this",2,"keep"],"false"]
[["filter_this",2,"extra"],"non-keeper"]
[["filter_this",2,"extra"]]
[["filter_this",2]]
[["filter_this"]]
Run Code Online (Sandbox Code Playgroud)
看来我需要选择所有“filter_this”行,仅截断这些行(使用“truncate_stream”),将这些行重建为对象(使用“from_stream”),过滤它们,然后将对象转回流数据格式(使用“tostream”)加入“保持不变”行的流,这些行仍处于流格式。那时就可以重新构建整个 json。如果这是正确的方法 - 这对我来说似乎过于复杂 - 我该怎么做?或者,还有更好的方法?
如果您的输入文件包含一个非常大的 JSON 实体,该实体对于常规 jq 解析器来说太大,无法在您的环境中处理,那么您很可能没有足够的内存来重建 JSON 文档。
考虑到这一点,以下方法可能值得一试。关键的见解是可以使用 来完成重建reduce。
为了清楚起见,下面使用了一堆临时文件:
TMP=/tmp/$$
jq -c --stream 'select(length==2)' input.json > $TMP.streamed
jq -c 'select(.[0][0] != "filter_this")' $TMP.streamed > $TMP.1
jq -c 'select(.[0][0] == "filter_this")' $TMP.streamed |
jq -nc 'reduce inputs as [$p,$x] (null; setpath($p;$x))
| .filter_this |= map(select(.keep=="true"))
| tostream
| select(length==2)' > $TMP.2
# Reconstruction
jq -n 'reduce inputs as [$p,$x] (null; setpath($p;$x))' $TMP.1 $TMP.2
Run Code Online (Sandbox Code Playgroud)
{
"keep_untouched": {
"keep_this": [
"this",
"list"
]
},
"filter_this": [
{
"keep": "true"
},
{
"keep": "true",
"extra": "keeper"
}
]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1794 次 |
| 最近记录: |