【问题标题】:Bash script print output in json formatBash 脚本以 json 格式打印输出
【发布时间】:2016-09-04 02:22:49
【问题描述】:

我正在尝试卷曲网页并对其进行一些处理,最后我尝试以 json 格式打印。(实际上需要在 mongodb 输入中)

所以输入(通过 curl 读取)是

输入:

brendan google engineer
stones microsoft chief_engineer
david facebook tester

对于处理类型,我将值分配给变量($name、$emloyer、$designation)

我最终转换为 json 的命令是,

echo [{\"Name\":\"$name\"},{\"Employer\":\"$employer\"},{\"dDesignation\":\"$designation\"}]

当前的输出是,

[{"Name":"brendan","Employer":"google","Designation":"engineer"}]
[{"Name":"stones","Employer":"microsoft","Designation":"chief_engineer"}]
[{"Name":"david","Employer":"facebook","Designation":"tester"}]

但是,我希望在同一行中的输出在开头和结尾用逗号和方括号分隔(不是在每一行上)

预期输出:

  [{"Name":"brendan","Employer":"google","Designation":"engineer"},{"Name":"stones","Employer":"microsoft","Designation":"chief_engineer"},
    {"Name":"david","Employer":"facebook","Designation":"tester"}]

任何建议。

【问题讨论】:

  • 如果要生成 JSON,为什么还要关心换行符在哪里?您应该关心解析树和文档模型的外观——如果您需要关心元素之间的空白类型,那么您的消费者(解析您生成的代码的人)做错了。
  • ...特别是,MongoDB 肯定不关心您在语法相关位置(例如字符串内容)之外是否有换行符或空格。

标签: linux bash shell awk sed


【解决方案1】:

传统的文本处理工具在一般情况下无法做到这一点。 JSON 有很多极端情况——例如,不可打印和高 Unicode 字符(和引号)需要转义。使用为工作实际构建的工具,例如jq:


jq -n -R '
[
  inputs |
  split(" ") |
  { "Name": .[0], "Employer": .[1], "Designation": .[2] }
]' <<EOF
brendan google engineer
stones microsoft chief_engineer
david facebook tester
EOF

...作为输出发射:

[
  {
    "Name": "brendan",
    "Employer": "google",
    "Designation": "engineer"
  },
  {
    "Name": "stones",
    "Employer": "microsoft",
    "Designation": "chief_engineer"
  },
  {
    "Name": "david",
    "Employer": "facebook",
    "Designation": "tester"
  }
]

【讨论】:

  • 完美!!如果您有其他选择,您会推荐什么工具?
  • 如果安装 jq 不是一个选项,我通常的后备方案是嵌入 Python 的 sn-p,因为那里的标准库中有一个出色的 json 模块。
  • 我虽然是关于 perl 的,但我猜这些天 jq 在 unices 上越来越可用了。无论如何,很好的答案++
  • 非常有帮助,第一次听说JQ,可以从curl给输入吗?因为我正在对 curl 文件进行一些处理,并且还添加了一些除 curl 之外的其他变量。
  • Curl 写入标准输出,jq 从标准输入读取;所以是的,只需将此处的文档替换为来自curl 的管道即可。
【解决方案2】:

这样的?

sep='['
curl "...whatever..." |
while read -r name employer designation; do
    printf '%s{"Name": "%s", "Employer": "%s", "Designation": "%s"}' "$sep" "$name" "$employer" "$designation"
    sep=', '
done
printf ']\n'

我同意这是脆弱且容易出错的;如果您可以使用像 jq 这样的 JSON 感知工具,请务必这样做。

【讨论】:

  • @CharlesDuffy 确实,输入时不假思索 - 现在已修复,感谢您的诊断!
  • @tripleee 这个其实效果很好,可以写成mongodb查询吗?就像 db.testcollection.insert([{"Name": "brendan","Employer": "google","Designation": "engineer"},{"Name": "stones","Employer": "microsoft","Designation": "chief_engineer"}])
  • 不知道你想去哪里。如果您只想将它​​添加到我们打印的文本中,那么更改应该是显而易见的。
【解决方案3】:

如果您可以访问 jq 1.5 或更高版本,那么您可以使用inputs,并且可能希望考虑使用splits(" +"),以防令牌可能被多个空格分隔:

jq -n -R '
  [inputs
   | [splits(" +")]
   | { "Name": .[0], "Employer": .[1], "Designation": .[2] }]'

如果您无法访问 jq 1.5 或更高版本,请注意以下内容适用于 jq 1.4:

jq -R -s '
  [split("\n")[]
   | select(length>0)
   | split(" ")
   | { "Name": .[0], "Employer": .[1], "Designation": .[2] }]'

【讨论】:

    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 2020-06-11
    • 2017-04-09
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多