【问题标题】:How delete last comma in json file using Bash?如何使用 Bash 删除 json 文件中的最后一个逗号?
【发布时间】:2016-08-17 20:24:47
【问题描述】:

我编写了一些脚本,它获取 aws ec2 实例的所有用户数据,并回显到 local.json。这一切都是在我安装我的 node.js 模块时发生的。 我不知道如何删除 json 文件中的最后一个逗号。这是 bash 脚本:

#!/bin/bash
export DATA_DIR=/data
export PATH=$PATH:/usr/local/bin

#install package from git repository
sudo -- sh -c "export PATH=$PATH:/usr/local/bin; export DATA_DIR=/data; npm install git+https://reader:secret@bitbucket.org/somebranch/$1.git#$2"

#update config files from instance user-data
InstanceConfig=`cat /instance-config`
echo '{' >> node_modules/$1/config/local.json
while read line
do
   if [ ! -z "$line" -a "$line" != " " ]; then
      Key=`echo $line | cut -f1 -d=`
      Value=`echo $line | cut -f2 -d=`
      if [ "$Key" = "Env" ]; then
         Env="$Value"
      fi
      printf '"%s" : "%s",\n' "$Key" "$Value" >> node_modules/*/config/local.json
   fi
done <<< "$InstanceConfig"
sed -i '$ s/.$//' node_modules/$1/config/local.json
echo '}' >> node_modules/$1/config/local.json

以这种方式运行他:./script 我得到 json(OUTPUT),但在所有行中都带有逗号。这是我得到的 local.json:

{
    "Env" : "dev",
    "EngineUrl" : "engine.url.net",
}

我要做的只是删除 json 文件的最后一行 - 逗号(“,”)。 我尝试了很多方法,我在互联网上找到了。我知道它应该在最后一个“fi”(循环结束)之后。我知道它应该是这样的:

sed -i "s?${Key} : ${Value},?${Key} : ${Value}?g" node_modules/$1/config/local.json

或者这个:

sed '$ s/,$//' node_modules/$1/config/local.json

但它们不适合我。 有人可以帮我吗?谁知道 Bash 脚本? 谢谢!

【问题讨论】:

  • 文件是由什么生成的?它不是有效的 JSON;你应该解决这个问题并重新生成数据。
  • 请提供一些示例输入。
  • @chepner 由于逗号,它不是有效的 json。这是我的问题。如何删除逗号?这个 shell 脚本在实例中安装包并从 local.json 获取变量。
  • 要明确 - 我们将完全丢弃您当前的 shell 脚本,因为这是错误的方法。您需要发布样本的输入文件是您当前发布的 shell 脚本的输入。
  • 我同意@EdMorton。手动构建 JSON 绝对是错误的开始方式。那里的许多语言,Perl、Ruby、Python 等,都有编写和测试良好的 JSON 模块,可以用几行代码构建你的 JSON。提供输入文件可能会为您提供强大且可扩展的解决方案。

标签: json bash shell awk sed


【解决方案1】:

如果您愿意使用它, 对尾随逗号相当宽容:

xidel -s local.json -e '$json'
{
  "Env": "dev",
  "EngineUrl": "engine.url.net"
}
xidel - -se '$json' <<< '{"Env":"dev","EngineUrl":"engine.url.net",}'
#or
xidel - -se 'parse-json($raw,{"liberal":true()})' <<< '{"Env":"dev","EngineUrl":"engine.url.net",}'
{
  "Env": "dev",
  "EngineUrl": "engine.url.net"
}

【讨论】:

    【解决方案2】:

    您可以使用以下命令从无效 json 中删除所有尾随逗号:

    sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' FILE
    
    • sed -i.bak = 创建原始文件的备份,然后将更改应用到文件

    • ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' = 以, 结尾的任何内容,后跟
      “新行和}”。去掉上一行的,

    • FILE = 您要更改的文件

    【讨论】:

      【解决方案3】:

      如果您知道它是需要替换的最后一个逗号,那么一种相当可靠的方法是在“slurp”模式下使用 GNU sed,如下所示:

      sed -zr 's/,([^,]*$)/\1/' local.json
      

      输出:

      {
        "Env" : "dev",
        "EngineUrl" : "engine.url.net"
      }
      

      【讨论】:

      • @muzafarow:你需要使用 GNU 版本的 sed
      • 太棒了。我浪费了很多时间来查看尝试执行此操作的多行 sed 命令。
      • 这只会替换文件中的最后一个逗号。要替换 } 之前的每一个逗号,请使用 sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' FILE 参见 unix.stackexchange.com/a/485010/20661
      【解决方案4】:

      如果可用,这里是jq 版本:

      jq --raw-input 'split("=") | {(.[0]):.[1]}' /instance-config | jq --slurp 'add'
      

      可能有一种方法可以通过 jqpass 来实现,但我看不到它。

      【讨论】:

        【解决方案5】:

        如果您只是发布一些示例输入/输出,它会消除猜测,但如果这是您的输入文件:

        $ cat file
        Env=dev
        EngineUrl=engine.url.net
        

        如果你想做我认为你想做的事,那么你所需要的就是:

        $ cat tst.awk
        BEGIN { FS="="; sep="{\n" }
        {
            printf "%s    \"%s\" : \"%s\"", sep, $1, $2
            sep = ",\n"
        }
        END { print "\n}" }
        

        你会执行为:

        $ awk -f tst.awk file
        {
            "Env" : "dev",
            "EngineUrl" : "engine.url.net"
        }
        

        如果您愿意,也可以在 shell 脚本中内联执行 awk 脚本:

        awk '
        BEGIN { FS="="; sep="{\n" }
        {
            printf "%s    \"%s\" : \"%s\"", sep, $1, $2
            sep = ",\n"
        }
        END { print "\n}" }
        ' file
        {
            "Env" : "dev",
            "EngineUrl" : "engine.url.net"
        }
        

        与您发布的 shell 脚本相比,以上内容在其他方面都更加健壮、便携、高效和更好,因为它使用了正确的工具来完成这项工作。 UNIX shell 是一种环境,可以从该环境中调用具有某种语言的工具来对这些调用进行排序。它不是一种处理文本的语言,这就是为什么要正确处理它如此困难的原因。用于一般文本处理的 UNIX 工具是 awk,因此当您需要在 UNIX 中处理文本时,只需 shell 调用 awk 即可。

        【讨论】:

        • 你问的是XY Problem,比如“用什么锤子来粉刷我的房子最好?”。几年后(或者更早,如果/当它开始隐秘地失败,具体取决于您的输入文件、环境等的内容),您将查看您的脚本并想知道您到底在想什么。你向某人Who knows Bash scripting well? 寻求帮助,你得到了某人的回答。您可能想阅读 shell 教程或类似内容的介绍,例如Chris Johnson 的《Shell Scripting Recipes》一书。同时 - 祝你好运!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-25
        • 2017-01-10
        • 1970-01-01
        • 2022-12-05
        • 2015-10-05
        相关资源
        最近更新 更多