【问题标题】:jq with multiple select statements and an array带有多个 select 语句和一个数组的 jq
【发布时间】:2021-05-19 10:22:02
【问题描述】:

我有一些类似下面的 JSON(我在这里过滤了输出):

[
  {
    "Tags": [
      {
        "Key": "Name",
        "Value": "example1"
      },
     {
        "Key": "Irrelevant",
        "Value": "irrelevant"
      }
    ],

    "c7n:MatchedFilters": [
      "tag: example_tag_rule"
    ],
    "another_key": "another_value_I_dont_want"
  },
  {
    "Tags": [
      {
        "Key": "Name",
        "Value": "example2"
      }
    ],

    "c7n:MatchedFilters": [
      "tag:example_tag_rule",
      "tag: example_tag_rule2"
    ]
  }
]

我想创建一个 csv 文件,其中包含 Name 键中的值以及数组中的所有“c7n:MatchedFilters”。我做了一些尝试,但仍然无法获得我期望的输出。下面是一些示例代码和输出:

#Prints the key that I'm after.
cat new.jq | jq '.[] | [.Tags[], {"c7n:MatchedFilters"}] | .[] | select(.Key=="Name")|.Value'
"example1"
"example2"

#Prints all the filters in an array I'm after.
cat new.jq | jq -r '.[] | [.Tags[], {"c7n:MatchedFilters"}] | .[] | select(."c7n:MatchedFilters") | .[]'
[
  "tag: example_tag_rule"
]
[
  "tag:example_tag_rule",
  "tag: example_tag_rule2"
]

#Prints *all* the tags (including ones I don't want) and all the filters in the array I'm after.
cat new.jq | jq '.[] | [.Tags[], {"c7n:MatchedFilters"}] | select((.[].Key=="Name") and (.[]."c7n:MatchedFilters"))'
[
  {
    "Key": "Name",
    "Value": "example1"
  },
  {
    "Key": "Irrelevant",
    "Value": "irrelevant"
  },
  {
    "c7n:MatchedFilters": [
      "tag: example_tag_rule"
    ]
  }
]
[
  {
    "Key": "Name",
    "Value": "example2"
  },
  {
    "c7n:MatchedFilters": [
      "tag:example_tag_rule",
      "tag: example_tag_rule2"
    ]
  }
]

我希望这是有道理的,如果我遗漏了什么,请告诉我。

【问题讨论】:

  • 我已经编辑了您的示例输入以使其成为有效的 JSON,您可以 check 我没有搞砸任何事情吗?
  • 请在问题中包含您的样本的预期输出。
  • @Aaron 非常感谢!我添加了一个额外的语句来证明这个失败。
  • @oguzismail 我已根据您的建议添加了输出。
  • 您想要的输出的具体示例下次会有所帮助。

标签: json export-to-csv jq


【解决方案1】:

您的尝试没有奏效,因为您从[.Tags[], {"c7n:MatchedFilters"}] 开始构造一个包含所有标签的数组和一个包含过滤器的对象。然后,您正在努力寻找一种方法来一次处理整个数组,因为它将这些不相关的东西混在一起,没有任何区别。如果您不首先将它们结合起来,您会发现它会容易得多!

您希望找到具有Key"Name" 的单个标签。这是找到它的一种方法:

first(
    .Tags[]|
    select(.Key=="Name")
).Value as $name 

通过使用变量绑定,我们可以将其保存以备后用,而不必担心单独构造数组。

您说(在 cmets 中)您只想将过滤器与空格连接起来。你可以很容易地做到这一点:

(
    ."c7n:MatchedFilters"|
    join(" ")
) as $filters

您可以将所有这些组合在一起,如下所示。请注意,每个变量绑定都会使输入流保持不变,因此很容易组合所有内容。

jq --raw-output '
    .[]|

    first(
        .Tags[]|
        select(.Key=="Name")
    ).Value as $name|

    (
        ."c7n:MatchedFilters"|
        join(" ")
    ) as $filters|

    [$name, $filters]|

    @csv

希望这很容易阅读并区分每个概念。我们将数组分解为对象流。对于每个对象,我们找到名称并将其绑定到$name,连接过滤器并将它们绑定到$filters,然后构造一个包含两者的数组,然后将数组转换为 CSV 字符串。

我们不需要使用变量。我们可以用一个大的数组构造函数包裹表达式来查找名称和表达式来查找过滤器。但我希望你能看到变量让事情变得更平淡,更容易理解。

【讨论】:

  • 您已经非常深入地解释了这一点,我非常感谢。这对于计划使用 jq 进行此类工作的几乎任何人和每个人都很有用,它非常好且详细。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
  • 2018-02-16
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多