如何组合(连接)包含公共密钥名称但在jq

时间:2016-11-03 09:49:13

标签: json jq

使用 jq 命令,我尝试将某些数据转换为特定格式

我有一个示例JSON集:

  • {
      "site": [
        {
          "uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
          "testtype": "Scheduled",
          "name": "JANE DOE HEAD OFFICE",
          "equip": "Unique Item One"
        }
      ]
    }
    {
      "site": [
        {
          "uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
          "testtype": "Scheduled",
          "name": "JANE DOE HEAD OFFICE",
          "equip": "Unique Item Two"
        }
      ]
    }
    {
      "site": [
        {
          "uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
          "testtype": "Scheduled",
          "name": "JANE DOE HEAD OFFICE",
          "equip": "Unique Item Three"
        }
      ]
    }

我想提取 唯一 值( equip );

  • 在数据集中使用 常见 名称的已知位置( site );
  • 将值与 字符串 分隔符连接起来,我可以更改;

  • 为了获得这样的输出:(以 comma 作为我选择的分隔符显示):

  • {
      "site": [
        {
          "uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
          "testtype": "Scheduled",
          "name": "JANE DOE HEAD OFFICE",
          "equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\""
        }
      ]
    }

仅作为第一步处理equip值;我尝试使用样本数据集的一些命令组合(将输出裁剪到每个上的第一个k:v对):

  • 尝试 -j 标志:(问题: Tailing 逗号)
    jq -jr '.site[].equip | . + ","' 
    
    Unique Item One,Unique Item Two,Unique Item Three,

  • 使用 Reduce (问题:主要逗号)

    jq -j '.site[].equip | reduce . as $item (""; "" + "," + ($item))'
    
    ,Unique Item One,Unique Item Two,Unique Item Three
  • 使用 join() :(问题:未正确使用,因此根本没有comma

    jq '.site | map(.equip) | join(",")'
    
    "Unique Item One" "Unique Item Two" "Unique Item Three"

  • 使用 @csv :(问题:尾随 comma,甚至不是来自@csv)
    jq -rj '.site[].equip + "," | [.] | @csv'
    
    "Unique Item One,""Unique Item Two,""Unique Item Three,"

我尝试过的其他事情会产生一个引导逗号,或者递归地连接和串联每一个对象,但我得出的结论是,我从根本上看错了。

  • 如果我带来外部输入进行测试,(在这种情况下传递 - arg )我可以接近使用赋值运算符进一步推进所需的结果,但它仍然为每个结果生成一行,并且变得非常不灵活:

  • jq -c --arg new2 "Unique Item Two" --arg new3 "Unique Item Three" -r '.site[] |= .equip + "," + $new2 + "," + $new3 | add | .[] | tojson'
    
    "Unique Item One,Unique Item Two,Unique Item Three"

现在我不确定我是否遗漏了一些简单的东西,或者这是否需要进行复杂的计数和迭代。

注意:我知道在外部削减输出是多么容易 - 有一些原因我想在 jq 中完全执行此操作,因为它&# 39;我真正想要的结构是正确的。

1 个答案:

答案 0 :(得分:3)

您可以将它们分组以确定需要合并的equip值,然后您可以构建字符串。

$ jq -n --arg delim ',' '{
    site: [inputs.site[]]
        | group_by(.uuid)
        | map({
            uuid: .[0].uuid,
            testtype: .[0].testtype,
            name: .[0].name,
            equip: (map(.equip | tojson) | unique | join($delim))
        })
}' input.json

这会产生:(注意:项目顺序不一定保留)

{
  "site": [
    {
      "uuid": "23451fae-a14f-49d1-a096-8f033f69dc80",
      "testtype": "Scheduled",
      "name": "JANE DOE HEAD OFFICE",
      "equip": "\"Unique Item One\",\"Unique Item Two\",\"Unique Item Three\""
    }
  ]
}

如果字符串看起来像csv数据并且需要转义,请务必这样做。假设需要转义引号,您可以修改此部分:

map(.equip | gsub("\"";"\"\"") |  tojson)