Json 使用jq的意外循环

Json 使用jq的意外循环,json,jq,Json,Jq,我正在尝试使用jq将bash中的表从json打印到标准输出: [ { "key": "name", "doc_count": 1000, "values_over_time": { "buckets": [ { "key_as_string": "2019-05-01 11:00:00.000", "key": 1556708400000, "d

我正在尝试使用
jq
将bash中的表从json打印到标准输出:

[
    {
      "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
文档,但无法理解正确的迭代方式。你有什么线索吗


您将
值在一段时间内展开两次
,从而生成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的操作方式,它将为这些子表达式的每个组合生成结果

查看您的过滤器和输入,下面是每个子表达式生成的结果数:

(.[].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

非常感谢-你是我大脑的救星!将尝试使用
jq
语法和迭代进行更多实验,感谢这些示例。现在我也知道
-nc
是一个随时都在身边的小游乐场。
.[] | "\(.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