使用JQ从刀搜索生成CSV

rb1*_*980 4 csv chef jq

JQ 看起来是一个很棒的工具,但我正在为它而苦苦挣扎。这是我想要做的:只从这个厨师刀搜索中提取值并生成一个 CSV。

鉴于此命令和输出:

刀搜索节点 "name:foo*" -a name -a cpu.total -a memory.total -Fj

{
  “结果”:2,
  “行”:[
    {
      “foo-01”:{
        "name": "foo-01",
        "cpu.total": 12,
        "memory.total": "16267368kB"
      }
    },
    {
      “foo-02”:{
        "name": "foo-02",
        "cpu.total": 12,
        "memory.total": "16264296kB"
      }
    }
  ]
}

我想像这样将值提取到 CSV 中:

foo-01,12,16267368kB
foo-02,12,16264296kB

(我可以处理报价)

Mic*_*mer 9

... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | map(tostring) | join(",")'
Run Code Online (Sandbox Code Playgroud)

这个:

  1. 扩展阵列.rows到输出流(.rows.[])。
  2. 流入下一步 ( |) 的管道
  3. 将它给定的对象扩展为(在本例中)它包含的单个值 ( .[])。
  4. 创建一个数组与的结果.name.["cpu.total"].["memory.total"] 在该对象上的每个评价.[ .name, ... ])。
  5. 将该数组的所有值转换为字符串( map(tostring))。
  6. 用逗号 ( join(","))连接每个数组的元素

jq -r输出原始数据,而不是引用和转义它。然后输出是:

foo-01,12,16267368kB
foo-02,12,16264296kB
Run Code Online (Sandbox Code Playgroud)

如你所愿。根据您的 CSV 解析器和实际数据,您可能需要在字符串周围额外引用,您可以添加或使用它@csv来代替最后两个步骤。

... | jq -r '.rows[] | .[] | [.name, .["cpu.total"], .["memory.total"]] | @csv'
Run Code Online (Sandbox Code Playgroud)

我们可以map通过只转换里面的一个值来跳过,这需要一些额外的括号:

... | jq -r '.rows[]|.[]|[.name, (.["cpu.total"] | tostring), .["memory.total"]] | join(",")'
Run Code Online (Sandbox Code Playgroud)

可能是最丑陋的选择:

... | jq -r '.rows[]|to_entries|.[]|.key + "," + (.value["cpu.total"] | tostring) + "," + .value["memory.total"]'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们不依赖.name字段,而是手动构建整个字符串。如果您需要高度自定义的格式,这是最灵活的选择。