如何将 jq 用作大型 json 文件的 SED(可选地使用映射 table)

How to use jq as SED for large json file (optionally with a mapping table)

我有一个很大的 json 文件,其中包含 json 文件中的多个 IP。我想替换 json 文件中的特定 IP 地址(无需将输出写入新文件)。等效的 SED 命令是 sed -i 's/old_ip/new_ip/g'

结构如下(json 文件中的单个 json 条目):

{

   "destination":{
      "port":53,
      "bytes":100,
      "ip":"1.1.1.1"
   },
   "source":{
      "port":54894,
      "bytes":84,
      "ip":"10.1.1.49",
   },
   "related":{
      "ip":"10.5.5.45"
   },
   "event":{
      "code":"0000000013",
      "action":"accept",
      "type":[
         "allowed",
         "connection",
         "end",
         "protocol"
      ],
      "outcome":"success"
   },
   "@timestamp":"2021-08-29T04:47:10.000+02:00"
}

我现在有两个问题无法解决。

问题一: 我想用相应的 IP 地址替换每个 IP。所以想象一下我想用 10.10.10.10

替换 IP 10.1.1.49

我知道我可以使用命令 jq '(.. | .ip?)' | select(.ip == "10.2.1.49")| .ip |= "10.10.10.10"' 但不幸的是,这只是输出新 IP,而不是像 SED 那样在文件中替换它(这是指我在网上找到的所有解决方案)。

问题二: 现在假设我有一个具有以下结构的映射 table (mapping.json):

{
 "10.2.1.49":"10.10.10.10",
 "10.15.15.15":"10.10.10.10"
}

我能否提供此映射 table 并将其与 jq 结合起来以进行查找和替换?我觉得这在 jq 中是不可能的,这意味着我需要弄清楚我的第一个问题,然后编写一个 bash 脚本。有人通过使用 --sluprfile 提出了类似的问题 ()。但显然我不能使用此 link 中的解决方案,因为需要 ID 或唯一的选择值,而我的 json.

中没有

是否有简单的解决方案,或者我应该将 SED 与 shellscript 结合使用? 谢谢

关于问题 1

可以使用

更新相关IP地址
jq '(.. | .ip? | select(. == "10.1.1.49")) |= "10.10.10.10"'
{
  "destination": {
    "port": 53,
    "bytes": 100,
    "ip": "1.1.1.1"
  },
  "source": {
    "port": 54894,
    "bytes": 84,
    "ip": "10.10.10.10"
  },
  "related": {
    "ip": "10.5.5.45"
  },
  "event": {
    "code": "0000000013",
    "action": "accept",
    "type": [
      "allowed",
      "connection",
      "end",
      "protocol"
    ],
    "outcome": "success"
  },
  "@timestamp": "2021-08-29T04:47:10.000+02:00"
}

Demo

但是您不能 像使用sed -i 那样更新文件——至少不能只使用标志。但是,使用临时文件或 sponge 等可以正常工作。

关于问题 2

读入映射,例如使用 --argfile 并使用查找结合替代运算符 // 进行更新以回退到原始值(如果它不存在于映射

中)
jq --argfile mapping mapping.json '(.. | .ip? // empty) |= ($mapping[.]? // .)'

Demo