多行 JSON 卷曲

Posted

技术标签:

【中文标题】多行 JSON 卷曲【英文标题】:Curl with multiline of JSON 【发布时间】:2016-04-23 05:25:11 【问题描述】:

考虑下面的 curl 命令,是否可以在 JSON 中允许换行符(没有缩小)并直接在 bash 中执行(Mac/Ubuntu)

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
'

    "field1": "test",
    "field2": 
        "foo": "bar"
    
'

当我运行上面的命令时,second 似乎发生了错误 如何修复上述命令?

更新:实际上我之前能够运行该命令而没有问题,不知道为什么最近会出现问题。

【问题讨论】:

你能告诉我们更多关于错误的信息吗?您的示例在我的系统上“按原样”运行。 mymac > bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) Copyright (C) 2007 Free Software Foundation, Inc. 是的,也适用于我:GNU bash, version 4.3.42(1)-release 也可以查看ANSI C-like string syntax:echo $'here is a newline:\nand here is a tab:\t' application/json 是 JSON 数据的正确媒体类型 -- 请参阅 RFC4627 【参考方案1】:

我认为这可以是一个答案

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
--data-raw '

    "field1": "test",
    "field2": 
        "foo": "bar"
    
'

【讨论】:

【参考方案2】:

我记得 Bash 手册页和 detailed here 中描述的另一种使用“此处文档”的方法。 @- 表示从 STDIN 读取正文,而 << EOF 表示将脚本内容通过管道传输到“EOF”作为 STDIN 卷曲。这种布局可能比使用单独的文件或“回显变量”方法更易于阅读。

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: application/json; charset=utf-8' \
--data-binary @- << EOF

    "field1": "test",
    "field2": 
        "foo": "bar"
    

EOF

注意:使用--trace &lt;outfile&gt; curl 选项准确地记录通过网络传输的内容。出于某种原因,这种 Here Document 方法去除了换行符。 (更新:curl -d 选项去除了换行符。已更正!)

【讨论】:

这很干净,没有额外的引用,没有转义,而且效果很好。谢谢。 我们可以使用这种语法的管道吗? 是的,您可以将输出通过管道传输到另一个命令,尽管位置就在中间。在标准输入重定向之后添加标准输出重定向。使用字数统计的示例:-d @- &lt;&lt; EOF | wc 去除新行的不是 Here Document,而是 curl -d 选项:curl.haxx.se/docs/manpage.html#-d。使用--data-binary 保留换行符和回车符。 可以在 JSON 中插入变量吗?我不这么认为。【参考方案3】:

由于某种原因,这种 Here Document 方法去除了换行符

@eric-bolinger Heredoc 去除换行符的原因是因为您需要通过引用 EOF 来告诉 Heredoc 保留换行符:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @- <<'EOF'


    "field1": "test",
    "field2": 
        "foo": "bar"
    

EOF

请注意第一次定义 EOF 时围绕它的单个刻度,但不是第二次。

【讨论】:

【参考方案4】:

按照 Martin 将 JSON 放入变量中的建议,您也可以将 JSON 放入单独的文件中,然后使用 curl 的 @ 语法将文件名提供给 -d

curl -0 -v -X POST http://www.example.com/api/users \
  -H "Expect:" \
  -H 'Content-Type: text/json; charset=utf-8' \
  -d @myfile.json

缺点很明显(以前有 2 个或多个文件。)但从好的方面来说,你的脚本可以接受文件名或目录参数,你永远不需要编辑它,只需在不同的地方运行它JSON 文件。这是否有用取决于您要完成的工作。

【讨论】:

注意:确保您通过jsonlint.com获得有效的json内容 与其他方法相比,这种方法干净且易于调试。 很好的解决方案。小心 PATH !【参考方案5】:

您可以将您的 json 分配给一个 var:

json='

    "field1": "test",
    "field2": 
        "foo": "bar"
    
'

现在您可以使用 stdin 将其转发给 curl:

echo $json | curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @-

【讨论】:

使用单引号将块括起来意味着您不能在 JSON 中使用变量(例如 $username)。 是的,但是使用双引号意味着您不能在数据中使用 $ 符号。选择适合您的。【参考方案6】:

您应该使用外部双引号,并转义所有内部引号,如下所示:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
"

    \"field1\": \"test\",
    \"field2\": 
        \"foo\": \"bar\"
    
"

【讨论】:

以上是关于多行 JSON 卷曲的主要内容,如果未能解决你的问题,请参考以下文章

使用 UNIX 命令行工具将 JSON 拆分为多行

使用 Python 从 MySQL 中的 JSON 对象插入多行

将 JSON 多行文件加载到 pyspark 数据框中

单个 Executor 正在处理巨大的多行 Json 文件

如何将 CSV 文件转换为多行 JSON?

使用 Apache PIG 读取多行 JSON