【问题标题】:Merge multiple objects under a single object and add sibling object in one command将多个对象合并到一个对象下,并在一个命令中添加同级对象
【发布时间】:2021-09-14 14:58:57
【问题描述】:

所以我有三个文件:

cats.json

{
  "cats": [
    {
      "name": "fluffles",
      "age": 10,
      "color": "white"
    }
  ]
}

dogs.json

{
  "dogs": [
    {
      "name": "sam",
      "age": 5,
      "color": "black and white"
    },
    {
      "name": "rover",
      "age": 2,
      "color": "brown and white"
    }
  ]
}

snakes.json

{
  "snakes": [
    {
      "name": "noodles",
      "age": 10,
      "color": "green"
    }
  ]
}

我想将它们合并到一个“动物”对象下。我发现这会合并文件:

jq -s '{"animals": .} ' cats.json dogs.json snakes.json > animals.json
{
  "animals": [
    {
      "cats": [
        {
          "name": "fluffles",
          "age": 10,
          "color": "white"
        }
      ]
    },
    {
      "dogs": [
        {
          "name": "sam",
          "age": 5,
          "color": "black and white"
        },
        {
          "name": "rover",
          "age": 2,
          "color": "brown and white"
        }
      ]
    },
    {
      "snakes": [
        {
          "name": "noodles",
          "age": 10,
          "color": "green"
        }
      ]
    }
  ]
}

现在我有一个额外的对象:

owners.json

{
  "owners": [
    "peter",
    "william",
    "sally"
  ]
}

我想合并到同一个文件中

jq -s '.[0] + .[1]' animals.json owners.json

我可以只用一个jq 命令完成这两项操作吗?

jq -s '{"animals": .} ' cats.json dogs.json snakes.json > animals.json
jq -s '.[0] + .[1]' animals.json owners.json

结果如下所示:

{
  "animals": [
    {
      "cats": [
        {
          "name": "fluffles",
          "age": 10,
          "color": "white"
        }
      ]
    },
    {
      "dogs": [
        {
          "name": "sam",
          "age": 5,
          "color": "black and white"
        },
        {
          "name": "rover",
          "age": 2,
          "color": "brown and white"
        }
      ]
    },
    {
      "snakes": [
        {
          "name": "noodles",
          "age": 10,
          "color": "green"
        }
      ]
    }
  ],
  "owners": [
    "peter",
    "william",
    "sally"
  ]
}

【问题讨论】:

    标签: json shell command-line jq


    【解决方案1】:

    假设您有一个(先验的)不确定或大量类型的动物,并且只有一个 owners 文件。在这种情况下,最好不要使用-s 选项(以节省内存),并且使用所有者文件作为第一个数据文件来调用 jq 会更容易,例如大致如下:

    jq -n -f program.jq owners.json $(ls *.json | grep -v owners.json)
    

    其中 program.jq 包含一个程序,例如:

    input as $owners | {$owners, animals: [inputs]}
    

    (注意{"owners": $owners} 是如何缩写的。)

    【讨论】:

    • 有趣。我实际上并没有想到-f 选项。我认为这是优化的答案,我会将其标记为已接受。在我的用例中,我碰巧有 n 只动物。
    • 作为对此的后续问题。是否可以指定多个输入,例如owners.json
    • 是的,例如,您可能希望考虑多次使用 --argfile 选项。哪个选项最好取决于细节。
    • 在这种情况下,它与所有者对象完全相同。
    • 如果我有一个{"food":["meat","fish","vegetables"]} 对象并且我想附加它,我将如何修改program.jq?执行会是jq -n -f program.jq owners.json food.json $(ls *.json | grep -v 'owners.json|food.json')吗?
    【解决方案2】:

    不确定这是否是可行的方法,但它通过以下方式获得所需的输出:

    • 使用--slurp:
    • 将前 3 个文件作为单个数组变量捕获
      [ .[0] * .[1] * .[2] ] as $all
    • owners 对象作为单个变量捕获
      .[3].owners as $owners
    • 根据需要创建对象
      { "animals": $all, "owners": $owners }
    jq \
        --slurp \
        '[ .[0] * .[1] * .[2] ] as $all | .[3].owners as $owners | { "animals": $all, "owners": $owners }' cats.json dogs.json snakes.json owners.json
    

    将产生:

    {
      "animals": [
        {
          "cats": [
            {
              "name": "fluffles",
              "age": 10,
              "color": "white"
            }
          ],
          "dogs": [
            {
              "name": "sam",
              "age": 5,
              "color": "black and white"
            },
            {
              "name": "rover",
              "age": 2,
              "color": "brown and white"
            }
          ],
          "snakes": [
            {
              "name": "noodles",
              "age": 10,
              "color": "green"
            }
          ]
        }
      ],
      "owners": [
        "peter",
        "william",
        "sally"
      ]
    }
    

    【讨论】:

    • 我什至找到了一种让它适用于任意数量的动物的方法:jq -s '[ .[0] * .[1] * .[2] ] as $all | .[3].owners as $owners | { "animals": $all, "owners": $owners }' *.json ~/owners.json 所以我认为这可能是正确的答案。
    • 啊,不错,听起来很棒!但是第一个*.json 不也包括owners 文件吗?希望这不会造成任何问题。
    • 必须将其存储在不同的位置。请参阅上面的答案是一个替代解决方案,它确实解决了这个问题,并且更加优化。
    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2021-07-14
    • 2015-02-16
    • 2019-05-03
    • 2019-12-20
    相关资源
    最近更新 更多