我正在尝试使用jq
从bash中将表打印到stdout:
[
{
"key": "name",
"doc_count": 1000,
"values_over_time": {
"buckets": [
{
"key_as_string": "2019-05-01 11:00:00.000",
"key": 1556708400000,
"doc_count": 50
},
{
"key_as_string": "2019-05-02 12:00:00.000",
"key": 1556798400000,
"doc_count": 40
},
{
"key_as_string": "2019-05-02 13:00:00.000",
"key": 1556802000000,
"doc_count": 30
}
]
}
}
]
通过jq -r '(.[].key + " " + .[].values_over_time[][].key_as_string) + " " + (.[].values_over_time[][].doc_count|tostring)'
,我得到了以下结果:
"name 2019-05-01 11:00:00.000 50"
"name 2019-05-02 12:00:00.000 50"
"name 2019-05-02 13:00:00.000 50"
"name 2019-05-01 11:00:00.000 40"
"name 2019-05-02 12:00:00.000 40"
"name 2019-05-02 13:00:00.000 40"
"name 2019-05-01 11:00:00.000 30"
"name 2019-05-02 12:00:00.000 30"
"name 2019-05-02 13:00:00.000 30"
附加的循环级别有些奇怪,我希望只看到3行:
"name 2019-05-01 11:00:00.000 50"
"name 2019-05-02 12:00:00.000 40"
"name 2019-05-02 13:00:00.000 30"
阅读jq
文档,但无法理解正确整齐地进行正确迭代的正确方法。你有什么线索吗?
答案 0 :(得分:1)
您要扩展values_over_time
两次,因此将生成3 * 3 = 9个输出。做类似这样的事情:
.[] | .key + " " + (.values_over_time.buckets[] | "\(.key_as_string) \(.doc_count)")
比较这两个命令以清楚地看出差异:
$ jq -nc '[1,2,3] | [.[]*.[]]'
[1,2,3,2,4,6,3,6,9]
$ jq -nc '[1,2,3] | [.[]|.*.]'
[1,4,9]
答案 1 :(得分:0)
技术原因是您要组合会生成多个结果的表达式。而jq的运行方式,将为这些子表达式的每种组合生成结果。
看看您的过滤器和输入,这是每个子表达式生成多少个结果:
(.[].key + " " + .[].values_over_time[][].key_as_string) + " " + (.[].values_over_time[][].doc_count|tostring)
(1 1 3) 1 (3 | 1)
(1 * 1 * 3 = 3) 1 (3 * 1 = 3)
3 * 1 * 3 = 9
这就是为什么您必须始终务必小心使用产生多个结果的表达式(例如[]
)。
正如Oguz所指出的那样,您需要编写它,使得输入仅在表达式中扩展一次。通常最好在过滤器的开头。
这可以通过多种方式完成,我会这样写:
.[] | "\(.key) \(.values_over_time.buckets[] | "\(.key_as_string) \(.doc_count)")"
1 | (1) (3 | (1) (1))
1 | (1) (3 | 1 * 1 = 1)
1 | (1) (3 * 1 = 3)
1 | (1 * 3 = 3)
1 * 3 = 3
答案 2 :(得分:0)
或者,可以使用基于步行路径的unix实用程序 jtc
构建相同的表(其中,将取回值的逻辑编码到步行路径中):< / p>
bash $ <file.json jtc -w'[:][key]<k>v[-1]<key_as_string>l:<s>v[-1][doc_count]' -T'"{k} {s} {}"'
"name 2019-05-01 11:00:00.000 50"
"name 2019-05-02 12:00:00.000 40"
"name 2019-05-02 13:00:00.000 30"
bash $
分解步行路径(-w
)
[:]
-遍历每个JSON元素(从顶部/根开始)[key]<k>v
-然后处理key
记录并在k
名称空间中存储其值[-1]<key_as_string>l:<s>v
-上一级备份(寻址父级),并在该父JSON中找到标签为key_as_string
的每个(所有)元素,并记住s
命名空间中的每个值< / li>
[-1][doc_count]
-通过doc_count
-插值结果走动(最后一个值为doc_count
),并按照模板将其保留在命名空间k
和s
中
PS>披露:我是jtc
工具的创建者