【问题标题】:Remove all objects containing a specific value from a JSON file using JQ?使用 JQ 从 JSON 文件中删除包含特定值的所有对象?
【发布时间】:2021-10-16 12:54:18
【问题描述】:

Vivaldi 浏览器(基于 Chromium)的书签文件往往会累积大量 base64 编码的缩略图,占用大量空间,我想删除这些条目。该文件是一个 JSON 文件,条目如下所示:

{
  "date_added": "13215828073144281",
  "guid": "3ace3174-ea60-42c5-88cf-e535a150ae38",
  "id": "74",
  "meta_info": {
     "Thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgA....AUpSgFKUoBSlKA//2Q=="
  },
  "name": "RIPE WHOIS IP Address Database Search › Look up an IP addres… - iTools",
  "type": "url",
  "url": "http://itools.com/tool/ripe-whois-ip-address"
},

我已经有一个像这样的 jq 过滤器:

jq 'walk(if type == "object" then with_entries(select(.key | test("Thumbnail") | not)) else . end)' Bookmarks > Bookmarks2

问题是这也会删除包含自定义缩略图的条目,如下所示:

"Thumbnail": "chrome://vivaldi-data/local-image/aa0d8713-99c6-4fcb-a725-a29235c4e8b0",

所以问题是,我将如何仅删除包含或以字符串data:image 开头的缩略图条目?

【问题讨论】:

  • 我对 JQ(或 JSON 相关)不是很有经验,所以如果我没有使用上述正确的术语,我深表歉意。我也找不到与此特定案例完全匹配的另一个答案。
  • 我也不太了解jq,但解决方法是使用jq 只是为了漂亮地打印json,然后使用sed 删除包含"Thumbnail": "data:image 的行?那可能仍然是有效的 json?
  • @SamBob 是的,sed 会很好,但由于某种原因,它似乎会破坏 JSON,并清除所有内容,直到它从同步服务器获得新副本。虽然使用 jq 工具有效,但不知道为什么。

标签: json jq vivaldi


【解决方案1】:

这样的事情应该可以解决问题:

del(recurse | objects | select(has("Thumbnail")) .Thumbnail | select(startswith("data:image")))

【讨论】:

    【解决方案2】:

    您可以添加另一个约束 startswith("data:image") | notselect 以仅保留 .keyor 不匹配且 .value 不以这种方式开始的元素,从而导致:select((.key | test("Thumbnail") | not) or (.value | startswith("data:image") | not))。您甚至可以应用德摩根定律并将其简化为 select(((.key | test("Thumbnail")) and (.value | startswith("data:image"))) | not)

    不过,有一个更简单的方法:假设整体结构是一个数组,沿线

    [
      {
        "date_added": "13215828073144281",
        "guid": "3ace3174-ea60-42c5-88cf-e535a150ae38",
        ...
      },
      {
        "date_added": "13215828073144282",
        "guid": "3ace3174-ea60-42c5-88cf-e535a150ae39",
        ...
      },
      ...
    ]
    

    然后简单地调用

    jq 'map(del(.meta_info.Thumbnail | select(startswith("data:image"))))' Bookmarks
    

    【讨论】:

    • 谢谢 - 我尝试了简化的方法,但 jq 只是转储核心,我在测试东西时得到了很多,不确定它是 Cygwin 还是其他东西。
    • 其他的工作,但所有这些括号都让人困惑;)jq 'walk(if type == "object" then with_entries(select((.key | test("Thumbnail") | not) or (.value | startswith("data:image") | not))) else . end)' Bookmarks
    • 也许你的整体结构不是一个简单的数组,那么。不幸的是,我不知道 vivaldi 的导出数据结构,我只是试图去掉你的walk 的复杂性,然后应用一个map。但是,如果结构足够复杂,则使用@oguz 的方法,使用recurse,这在某种程度上类似于您的walk,但使用与我相同的技术(selectdel)。
    • 是的,它是一个复杂的结构,有好几层。有关示例(如果您有兴趣),请参阅:pastebin.com/S3r62qjk。我在那里添加了带有缩略图的 NRK 书签。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多