首页 > 解决方案 > 在所有文件中查找 JSON 键并移除对应的键值对

问题描述

我有很多文件需要在其中找到一个字符串,如果该字符串存在,那么我需要从所有这些文件中删除该字符串周围的 json 块。

例如:

我正在寻找这个字符串 -"1234"在我的所有文件中。每个文件都有一个巨大的 json 块,其中包含我要删除的字符串。所以在所有这些文件中,字符串如下两种格式:

第一种格式是:

...
"data": {
    "1234": {
        "tt": true
    }
}
...

数据中包含多个 json 对象的第二种格式:

...
"data": {
    "1234": {
        "tt": true
    },
    "7890": {
        "tt": true
    }
}
...

现在我需要想出一些可以"1234"完全删除 json 对象的脚本。所以输出应该是:

对于第一种格式:

...
"data": {}
...

对于第二种格式:

...
"data": {
    "7890": {
        "tt": true
    }
}
...

这可能吗?我在mac linux终端。我可以进行 grep 搜索并找到文件,但不确定如何从所有文件中删除该字符串周围的 json 对象。

注意:每个 json 文件的格式都很漂亮。

更新:

{
    "props": [
        {
            "property": "Hat",
            "data": {
                "1234": {
                    "tt": true
                },
                "7890": {
                    "tt": true
                }
            }
        }
    ]
}

这是片段 - https://jqplay.org/s/qXW_QUYFv0。如果property值是,Hat那么我只想删除存在的键,但如果属性值是其他值,那么我不想删除该键。有什么方法可以添加此更改吗?

标签: pythonbashsedgrepjq

解决方案


更新

鉴于更新的问题,请看看这个

jq '{props: [.props[] | (select(.property == "Hat") | del(.data["1234"])), select(.property != "Hat")]}'

在线尝试!

这只是 jq 表达式本身。要在文件夹等中的每个文件上运行它,只需在下面的 bash 循环中替换它。

这个怎么样 ...

jq 'delpaths([paths] | map(select(.[]=="1234")))'

第一个例子

输入

{
    "data": {
        "1234": {
            "tt": true
        }
    }
}

输出

{
  "data": {}
}

在线尝试!

第二个例子

输入

{
    "data": {
        "1234": {
            "tt": true
        },
        "7890": {
            "tt": true
        }
    }
}

输出

{
  "data": {
    "7890": {
      "tt": true
    }
  }
}

在线尝试!

一个简单的 bash 脚本,用于在每个文件(例如 data-1.json)上运行它并将其保存在适当的位置......

for file in *.json; do
    jq 'delpaths([paths] | map(select(.[]=="1234")))' <"$file" >"$file.new" && mv "$file.new" "$file"
done

在没有实际输入/输出而不是摘录的情况下,这是我所能得到的。

希望这可以帮助!


推荐阅读