【问题标题】:Remove trailing json comma with command line tools使用命令行工具删除结尾的 json 逗号
【发布时间】:2019-04-11 13:34:11
【问题描述】:

我想从 json 中删除尾随逗号,

{
  "key1": "value1",
  "object": {
    "key2": "value2", // <- remove comma
  },
  "key3": "value3", // <- remove comma
}

我想出了,

tr -d '\n' | \
sed -E 's:,(\s*}):\1:g' | \
jq .

它有效,但我想在sed 中完全得到它。

我想出了,

sed -E '/,\s*$/ { N; s:,\s*(\n\s*},?):\1: }'

适用于上述输入但失败

{
  "key1": "value1",
  "object": {
    "key2": "value2",
  },
  "key3": "value3",
  "key4": "value4", // <- remove comma
}

N 读取下一行并从下一行重新开始。

// output sed -E '/,\s*$/ { N;l }' using l/look command
{
  "key1": "value1",\n  "object": {$
  "key1": "value1",
  "object": {
    "key2": "value2",\n  },$
    "key2": "value2",
  },
  "key3": "value3",\n  "key4": "value4",$
  "key3": "value3",
  "key4": "value4",
}

更新:

添加另一个示例进行测试:

{
  "key1": "value1",
  "object1": {
    "object2": {
      "key2": "value2"
    },
  },
  "key3": "value3",
}

更新:

这对我扔给它的任何东西都有效。

sed -E -n 'H; x; s:,(\s*\n\s*}):\1:; P; ${x; p}' | \
    sed '1 d'

解释:

sed -E -n 'H; x; P; ${x; p}'

-n 'H; x' 将每一行附加到模式空间中的下一行(除了最后一行,它只是用${x; p} 打印)

s:,(\s*\n\s*}):\1:;

删除模式空间中的尾随逗号。

【问题讨论】:

  • 你能改掉生成无效 JSON 的东西吗?因为这并不是你要用sed 稳健地解决的那种问题。
  • 几乎所有语言都有 JSON 库。如果您收到这样的无效 JSON,则肯定表明创建者使用了自己的代码而不是使用适当的库,并且他们不知道自己在做什么。告诉他们修复它。
  • 因为如果他们连逗号都搞不懂,他们可能还会遇到其他问题,比如转义字符串中的特殊字符。试图解决他们所有的错误,你会让自己发疯。
  • 你所做的任何事情都可能会因为key: "foo,}" 而失败,它会删除字符串中的逗号。
  • "我想从 json 中删除尾随逗号" -- 您的输入不是 JSON(因为 JSONs 没有尾随逗号)。假设您的输入 JSON,sed 不是处理它的工具。使用jq 或编程语言。

标签: json bash sed


【解决方案1】:

使用保持缓冲区:

sed '/^ *\}/{H;x;s/\([^}]\),\n/\1\n/;b};x;/^ *}/d' input

这只是一个 sed 练习,我不认为 sed 是适合这项工作的工具。它还需要在末尾换行或文件以 } 结尾。

【讨论】:

  • 我添加了另一个示例 json 用于测试 sed 失败的地方。
  • 这不适用于我添加的新示例 json。你确定这个工作?我在和sed (GNU sed) 4.5GNU bash, version 4.4.19(2)-release (x86_64-pc-msys),所以我对差异感兴趣。顺便说一句,我更新了答案。
  • 总体而言,对于现在标题为 hjson 处理 cmets(双行、块)、尾随逗号的问题,接受的答案是更好的答案,但感谢您使用 sed 为我指明正确的方向。
【解决方案2】:

由于输入似乎是 JSON 的某种扩展,因此您可以使用用于此类扩展的命令行工具。例如:

$ hjson -j < input.txt

或:

$ any-json --input-format=hjson input.txt

两种情况下的输出

{
  "key1": "value1",
  "object": {
    "key2": "value2"
  },
  "key3": "value3"
}

【讨论】:

  • 好答案!另一方面, json 应该只支持尾随逗号! :)
【解决方案3】:

不是sed 的答案,而是 (python) 的解决方案:

# load as python dictionary
d = {
  "key1": "value1",
  "object": {
    "key2": "value2",
  },
  "key3": "value3",
}

import json

json.dumps(d) # valid json string

【讨论】:

    【解决方案4】:

    这是 GNU awk 中的一个。它使用" 作为字段分隔符,并从奇数字段中删除[ \n]*} 之前的逗号(外部引号,"escaped \" inside" 可能会失败)。在文件中添加了"key4": "value4,}",

    $ cat file
    {
      "key1": "value1",
      "object": {
        "key2": "value2",
      },
      "key3": "value3",
      "key4": "value4,}",
    }
    

    脚本将整个文件作为单个记录 (RS="^$") 处理,因此它可能无法按原样处理大文件:

    $ awk '
    BEGIN {
        FS=OFS="\""
        RS="^$"
    }
    {
        for(i=1;i<=NF;i++) {                         # or i+=2 and remove the if
            if(i%2)
                $i=gensub(/,([ \n]*\})/,"\\1","g",$i)
        }
    }1' file
    

    输出:

    {
      "key1": "value1",
      "object": {
        "key2": "value2"
      },
      "key3": "value3",
      "key4": "value4,}"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      相关资源
      最近更新 更多