【问题标题】:How to merge multiple Json files in folder in certain order如何按特定顺序合并文件夹中的多个 Json 文件
【发布时间】:2019-06-07 20:18:06
【问题描述】:

我在一个文件夹中有多个 JSON 文件,我想按照order.json 中给出的特定顺序将它们组合成一个文件

我已经测试了下面的代码,它合并了所有文件,但根据文件名按字母顺序排列。

jq -s . *.json > Merged.json

这是文件 Shoes.json

{ "document": { "product": "Shoes", "info": [ { "day": "1", "month": "1", "entry": "Some text about Shoes for day 1 and month 1", "code": "AJKD" }, { "day": "2", "month": "1", "entry": "Some text about Shoes for day 2 and month 1", "code": "KKGIR" } ] } }

这是文件 Watches.json

{ "document": { "product": "Watches",   "info": [ { "day": "2", "month": "3",   "entry": "Some text about Watches for day 2 and month 3",   "code": "PEWQ" }    ] }     }

这是文件 Accesories.json

{ "document": { "product": "Accesories",    "info": [ { "day": "7", "month": "2",   "entry": "Some text about Accesories for day 7 and month 2",    "code": "UYAAC" }   ] }     }

这是给出我想在输出中获得的顺序的文件 order.json

{  
   "order":{  
      "product 1":"Watches",
      "product 2":"Accesories",
      "product 3":"Shoes"
   }
}

我想得到的输出文件是这样的Merged.json

{  
   "document":[  
      {  
         "product":"Watches",
         "info":[  
            {  
               "day":"2",
               "month":"3",
               "entry":"Some text about Watches for day 2 and month 3",
               "code":"PEWQ"
            }
         ]
      },
      {  
         "product":"Accesories",
         "info":[  
            {  
               "day":"7",
               "month":"2",
               "entry":"Some text about Accesories for day 7 and month 2",
               "code":"UYAAC"
            }
         ]
      },
      {  
         "product":"Shoes",
         "info":[  
            {  
               "day":"1",
               "month":"1",
               "entry":"Some text about Shoes for day 1 and month 1",
               "code":"AJKD"
            },
            {  
               "day":"2",
               "month":"1",
               "entry":"Some text about Shoes for day 2 and month 1",
               "code":"KKGIR"
            }
         ]
      }
   ]
}

也许有人可以帮我处理这个案子。

任何帮助将不胜感激。

【问题讨论】:

    标签: json merge jq


    【解决方案1】:

    这里有一个解决方案,使用order.json来确定jq要读取哪些文件:

    jq -n '{documents: [inputs.document]}' $(jq -r '.order[] + ".json"' order.json)
    

    上面直接举例说明的方法有很多优点,但上面的行做了各种可能不成立的假设。例如,它假定任何文件名中都没有空格。

    强大的文件名处理

    以下假设具有 bash-ful 功能:

    mapfile -t args < <(jq -r '.order[] + ".json"' order.json)
    jq -n '{documents: [inputs.document]}' "${args[@]}"
    

    如果您的 bash 没有 mapfile,您可以按如下方式设置 bash 变量:

    args=()
    while read -r f; do 
      args+=("$f")
    done < <(jq -r '.order[] + ".json"' order.json)
    

    【讨论】:

    • 我根本不是专家,但第二个解决方案对我来说看起来更好,更短,更容易理解:)
    【解决方案2】:

    以下解决方案的优点是不需要任何特定于 shell 的功能,并且只需要一次 jq 调用。它假定您希望能够处理任意多个文件,由order.json 确定。其他假设是,在密码中,我们可以使用模式[A-Z]*.json 来选择相关的“文档”。

    jq -n --argfile order order.json '
      INDEX(inputs.document;  .product) as $dict
      | reduce $order.order[] as $product ([]; . + [$dict[$product]])
      | {document: .}
    ' [A-Z]*.json
    

    定义索引

    如果你的jq没有INDEX/2,那么可能是升级的好时机;或者,您可以简单地添加(前置)其 def:

    def INDEX(stream; idx_expr):
      reduce stream as $row ({}; .[$row|idx_expr|tostring] = $row);
    

    【讨论】:

    • 嗨,再次高峰。谢谢你的帮助。我已尝试使用我发布的相同文件,但我收到此错误jq: error: INDEX/2 is not defined at &lt;top-level&gt;, line 2: INDEX(inputs.document; .product) as $dict jq: 1 compile error。 jq 版本它说[version 1.5-1-a5b5cbe] 如果重要的话。
    • 我肯定需要升级。但与此同时,我测试了您添加 INDEX 函数的代码,它运行良好。如果您有机会,由于此解决方案较小,请您解释一下逻辑。每个步骤的作用是什么?再次感谢。
    • 您可以阅读标准 jq 文档中的 INDEX 和 reduce。您可能会发现使用jqplay.org 有助于巩固您的理解。如果您不熟悉“减少”的概念,您可能会发现这篇博文很有帮助——blog.differentpla.net/blog/2019/01/11/jq-reduce——但请注意第一部分包含一个错误。作为练习,您可能想尝试找到它。
    猜你喜欢
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    相关资源
    最近更新 更多