【问题标题】:Add values from a "key" JSON file to other files based on partial string matching using JQ基于使用 JQ 的部分字符串匹配,将“键”JSON 文件中的值添加到其他文件
【发布时间】:2021-07-28 02:14:53
【问题描述】:

目标是将 JSON 文件与标准值的“键”进行比较,如果某些字符串匹配,则将这些值添加到另一个 JSON 文件中的对象。目的是合并两组具有互补数据的分析。

我一直试图匹配的条件是 index-of-pages.json 中的href 在 key.json 中包含 url 中的字符串。

index-of-pages.json

[
    {
      "href": "articles/guide1/page1.html",
      "name": "Page 1",
      "views": "204"
    },
    {
      "href": "articles/guide2/page2.html",
      "name": "Page 2",
      "views": "180"
    },
    {
      "href": "articles/guide2/page3.html",
      "name": "Page 3",
      "views": "121"
    },
    {
      "href": "apis/apiguide1/subguide1/page4.html",
      "name": "Page 4",
      "views": "101"
    },
    {
      "href": "apis/apiguide2/subguide2/page5.html",
      "name": "Page 5",
      "views": "103"
    },
    {
      "href": "articles/guide1/about.html",
      "name": "Page 6",
      "views": "103"
    },
    {
      "href": "index.html",
      "name": "Page 7",
      "views": "400"
    }
]

key.json

[
    {
        "url": "/guide1/",
        "guide": "Guide 1",
        "tag": "how-to"
    },
    {
        "url": "/guide2/",
        "guide": "Guide 2",
        "tag": "how-to"
    },
    {
        "url": "/apiguide1/subguide1/",
        "guide": "API Guide 1",
        "subguide": "Subguide 1",
        "tag": "api"
    },
    {
        "url": "/guide1/about",
        "guide": "Guide 1",
        "tag": "about"
    }
]

请注意,最后一个对象的 url 上没有斜杠。

期望的结果:

[
    {
        "href": "articles/guide1/page1.html",
        "name": "Page 1",
        "views": "204",
        "url": "/guide1/",
        "guide": "Guide 1",
        "tag": "how-to"
    },
    {
        "href": "articles/guide2/page2.html",
        "name": "Page 2",
        "views": "180",
        "url": "/guide2/",
        "guide": "Guide 2",
        "tag": "how-to"
    },
    {
        "href": "articles/guide2/page3.html",
        "name": "Page 3",
        "views": "121"
    },
    {
        "href": "apis/apiguide1/subguide1/page4.html",
        "name": "Page 4",
        "views": "101",
        "url": "/apiguide1/",
        "guide": "API Guide 1",
        "subguide": "Subguide 1",
        "tag": "api"
    },
    {
        "href": "apis/apiguide2/subguide2/page5.html",
        "name": "Page 5",
        "views": "103"
    },
    {
        "href": "articles/guide1/about.html",
        "name": "Page 6",
        "views": "103",
        "url": "/guide1/about",
        "guide": "Guide 1",
        "tag": "about"
    },
    {
        "href": "index.html",
        "name": "Page 7",
        "views": "400"
    }
]

index-of-files.json 中与键中的任何内容都不匹配的对象仍将包含在所需的输出中。

是否希望所有键都包含在输出对象中,即使它们是空的,我不确定什么是最佳做法。

这让我最接近,但我不知道如何在键上加入一个步骤来匹配:

jq --argfile uid key.json '
 ($uid | INDEX(.url)) as $dict
 | map( $dict[.href] + del(.href) )
 ' index-of-files.json

以下其他尝试不会导致对象的 1:1 匹配;相反,它会生成每个键的所有可能组合的巨大列表(输出是嵌套的,因此我将其标记为 key;此脚本中未显示所有所需的输出键):

(.[].href/"/"?|{key: ("/" + .[-2] + "/")}) as $abc | {name: .[].name, level: $abc}

我还尝试了while if 循环的变体,但没有成功:

jq -r '.[] | "\(.url)|\(.guide)|\(.tag)|\(.subguide)"' key.json |
while IFS="|" read -r url guide tag subguide; do
cat index-of-files.json | jq --arg url "$url" --arg guide "$guide" --arg subguide "$subguide" '.[] | if (.href | contains('\"$url\"')) then . + {guide: '\"$guide\"', tag: '\"$tag\"', subguide: '\"$subguide\"'} else . end'
done

感谢您的任何见解或指导。

【问题讨论】:

    标签: bash jq


    【解决方案1】:

    我不认为INDEX 可以在这里提供帮助。

    我会这样做:

    sort_by(.url | -length) as $c | inputs | map(. + (.href as $s | first($c[] | select(.url as $ss | $s | index($ss))) // {}))
    

    如果不清楚,JQ 调用将如下所示:

    jq '...' key.json index-of-pages.json
    

    Online demo

    【讨论】:

    • 这非常有效。感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    相关资源
    最近更新 更多