【问题标题】:How to delete a Json object from Json File by sed command in BASH如何通过 BASH 中的 sed 命令从 Json 文件中删除 Json 对象
【发布时间】:2016-10-27 23:17:48
【问题描述】:

我有一个 JSON 文件,其中需要删除一个 JSON 对象。 有没有办法只使用 sed 命令删除它? 我的示例文件如下所示。

{
  "name": "ABC",
  "description": "XYZ",
  "versions": {},
  "json_class": "Chef::Environment",
  "chef_type": "environment",
  "default_attributes": {},
  "override_attributes": {
    "company": {
      "xyz": {
        "mailer": {
          "smtp_host": "Some IP",
          "imap_host": "Some Host",
          "imap_user": "Some UserId",
          "reply_to": "Some User Id",
          "outbound_user": "",
          "imap_mail_domain": "compute.oraclecloud.com",
          "imap_password": ""
        },
        "logicaldomainname": ""
      }
    }
  }
}

我想使用 sed 命令从文件中删除邮件对象。 请看一下,让我知道是否可以使用 sed 命令。

我这次删除的主要动机是用新的替换这个对象 mailer 对象,以便下次发布另一个 mailer 对象时,我们会将其附加到 xyz JSON 对象中。

预期输出:

{
  "name": "ABC",
  "description": "",
  "version": {},
  "json_class": "Chef::Environment",
  "chef_type": "environment",
  "default_attributes": {},
  "override_attributes": {
    "Company": {
      "XYZ": {
        "logicaldomainname": ""
      }
    }
  }
}

【问题讨论】:

  • 实际上 jq 由于我们机器中的一些许可规定,我们无法使用。但我们可以使用 awk,
  • sed 绝对不合适。如果jq 不是一个选项,您应该考虑使用 Perl 或 Python:它们有很棒的 json 库。
  • 添加了预期的输出..

标签: json bash awk sed


【解决方案1】:

使用sed:

sed '/\"mailer\"/,/}/ d; /^$/d' 1.a

“从mailer删除到第一个},然后删除所有空行(你输入有一个)”。

覆盖文件(“就地”)

sed -i ...

注意:适用于多行文件(与您一样)。

【讨论】:

  • 如果某人的用户ID是mailer?
  • 如果“mailer”中有一个嵌套的 JSON 对象怎么办?
  • 这非常适合删除 package.json 文件的“devDependencies”部分!谢谢!
【解决方案2】:

您应该强烈考虑解决禁止jq 的许可问题:

jq 'del(.override_attributes.company.xyz.mailer) | .description=""' input.json

【讨论】:

    【解决方案3】:
    $ awk -v RS='^$' -v ORS= '{sub(/"mailer":[^}]+},[[:space:]]+/,"")}1' file
    {
            "name": "ABC",
            "description": "",
            "versions": {
    
            },
            "json_class": "Chef::Environment",
            "chef_type": "environment",
            "default_attributes": {
    
            },
            "override_attributes": {
              "Company": {
                "XYZ": {
                        "logicaldomainname": ""
                          }
                          }
            }
        }
    

    以上使用 GNU awk 进行多字符 RS,使用其他 awk,您将一次建立一行记录并在 END 部分进行处理:

    $ awk -v ORS= '{rec=rec $0 RS} END{sub(/"mailer":[^}]+},[[:space:]]+/,"",rec); print rec}' file
    {
            "name": "ABC",
            "description": "",
            "versions": {
    
            },
            "json_class": "Chef::Environment",
            "chef_type": "environment",
            "default_attributes": {
    
            },
            "override_attributes": {
              "Company": {
                "XYZ": {
                        "logicaldomainname": ""
                          }
                          }
            }
        }
    

    【讨论】:

    • 感谢@ED Morton,第一个对我来说很好。
    • 第二个答案似乎正在打印预期的结果,但在原始文件中它没有改变,而第一个答案正在做同样的事情..
    • 不客气。给它几个小时看看你得到了什么其他答案,然后如果/当你决定接受单击它旁边的复选标记时(见stackoverflow.com/help/someone-answers)。
    • 两个脚本具有相同的行为,并且都不打算修改原始文件。 GNU awk 有一个 -i inplace 选项可以做到这一点(awk -i inplace '...script...' file),但通常使用任何 UNIX 命令 cmd 来修改您要执行的原始文件:cmd file > tmp && mv tmp file
    • "如果某人的用户 id 是mailer?"它会从它删除到第一个},...here more spaces...,对吧?
    猜你喜欢
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多