我建议您可以使用jq 来处理您的json 文件。 jq 能够读取 json 并格式化输出。这是一个示例 jq 脚本来处理您的 json 文件(我难以想象地称之为“jsonfile”):
jq -r '.[] | "curl -d '\'' \(.) '\'' http://restful.com/api " ' jsonfile
这是输出:
curl -d ' {"foo":"bar:baz:foo*","bar*":"baz*","etc":"etc"} ' http://restful.com/api
curl -d ' {"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"} ' http://restful.com/api
curl -d ' {"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"} ' http://restful.com/api
curl -d ' {"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"} ' http://restful.com/api
这是怎么回事:
我们将三个参数传递给jq 程序:jq -r
.[] | "some string \(.)"
第一个. 表示获取整个json 结构,[] 表示遍历结构中的每个数组元素。 | 是一个过滤器,用于处理数组中的每个元素。过滤器是输出一个字符串。我们使用\(.) 对传入| 过滤器的整个元素进行插值。
哇...我之前从未真正解释过jq 脚本(它显示了)。但关键是,我们使用 jq 查找 json 数组中的每个元素并将其插入到字符串中。我们的字符串是这样的:
curl -d '<the json dictionary array element>' http://restful.com/api
好的。你会看到输出。有用。但是等一下,我们只有输出。让我们告诉 shell 像这样运行每一行:
jq -r '.[] | "curl -d '\'' \(.) '\'' http://restful.com/api " ' jsonfile | bash
通过管道输出到 bash,我们执行我们输出的每一行。本质上,我们正在使用 jq 编写一个 bash 脚本来 curl http://restful.com/api 将 json 元素作为 -d 数据参数传递给 POST json 元素。
重温单引号问题
@oguz ismail 指出,如果 json 输入文件中有单引号,bash 会爆炸。这是真实的。我们可以通过转义来避免引用,但我们会获得更多的复杂性——这使得这不是理想的方法。
这是问题输入(我只是插入了一个单引号):
[{"foo":"bar:'baz:foo*","bar*":"baz*","etc":"etc"},
{"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"},
{"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"},
{"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"}]
请注意上面的baz 现在是'baz。问题是单引号使 bash shell 抱怨不匹配的引号:
$ jq -r '.[] | "curl -d '\'' \(.) '\'' http://restful.com/api " ' jsonfile | bash
bash: line 4: unexpected EOF while looking for matching `"'
bash: line 5: syntax error: unexpected end of file
解决办法如下:
$ jq -r $'.[] | "\(.)" | gsub( "\'" ; "\\\\\'" ) | "echo $\'\(.)\'" ' jsonfile | bash
{"foo":"bar'baz:foo*","bar*":"baz*","etc":"etc"}
{"foo2":"bar2:baz2:foo2*","bar2*":"baz2*","etc":"etc"}
{"foo3":"bar3:baz3:foo3*","bar3*":"baz3*","etc":"etc"}
{"foo4":"bar4:baz4:foo4*","bar4*":"baz4*","etc":"etc"}
上面我使用 $'' 来引用 jq 脚本。这允许我使用 ' 转义单引号。我还将curl 命令更改为echo,这样我就可以在不打扰http://restful.com/api 的人的情况下测试bash 脚本。
“诀窍”是确保我们生成的 bash 脚本也使用反斜杠转义所有单引号。因此,我们必须将' 更改为\'。这就是 gsub 正在做的事情。
gsub( "\'" ; "\\\\\'" )
在进行替换后(' --> \'),我们将整个字符串通过管道传输到此:
"echo $\'\(.)\'"
用echo $''包围gsub的输出。现在我们再次使用 $' 以便 bash 正确理解 \'。
所以当我们把卷曲放回原处时,我们就结束了:
jq -r $'.[] | "\(.)" | gsub( "\'" ; "\\\\\'" ) | "curl -d $\'\(.)\' http://restful.com/api " ' jsonfile | bash