首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Shell JSON循环到JSON

Shell JSON循环到JSON
EN

Stack Overflow用户
提问于 2016-12-11 01:54:06
回答 2查看 481关注 0票数 0

我有一个带两个变量的while循环,我必须合并成一个JSON片段,如下所示:

代码语言:javascript
复制
#!/bin/bash
while read -r from to
do
    # BONUS: Solution would ideally require no quoting at this point
    echo { \"From\": \"$from\", \"To\": \"$to\" } 
done << EOF
foo bar
what ever
EOF

它当前输出无效的JSON:

代码语言:javascript
复制
{ "From": "foo", "To": "bar" }
{ "From": "what", "To": "ever" }

最简单的方法是创建有效的JSON,如:

代码语言:javascript
复制
[
{ "From": "foo", "To": "bar" },
{ "From": "what", "To": "ever" }
]

我看了看jq,但我想不出怎么做。理想情况下,我不是looking to do it in shell,因为我觉得添加逗号有点难看。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-11 03:22:16

与jq:

代码语言:javascript
复制
$ jq -nR '[inputs | split(" ") | {"From": .[0], "To": .[1]}]' <<EOF
foo bar
what ever
EOF

[
  {
    "From": "foo",
    "To": "bar"
  },
  {
    "From": "what",
    "To": "ever"
  }
]

-n告诉jq不要读取任何输入;-R是用于原始输入的,因此它不需要JSON。

输入是用inputs读取的,因此每个输入行都有一个字符串:

代码语言:javascript
复制
$ jq -nR 'inputs' <<EOF
foo bar
what ever
EOF
"foo bar"
"what ever"

然后,将这些词分成几个字数组:

代码语言:javascript
复制
$ jq -nR 'inputs | split(" ")' <<EOF
foo bar
what ever
EOF

[
  "foo",
  "bar"
]
[
  "what",
  "ever"
]

由此,我们构造了以下对象:

代码语言:javascript
复制
$ jq -nR 'inputs | split(" ") | {"From": .[0], "To": .[1]}' <<EOF
foo bar
what ever
EOF

{
  "From": "foo",
  "To": "bar"
}
{
  "From": "what",
  "To": "ever"
}

最后,我们将所有内容封装在[]中,以便首先显示最后的输出。

直接拆分输入的更直观的方法失败了,因为将所有内容封装在[]中会导致每个输入行生成一个数组:

代码语言:javascript
复制
$ jq -R '[split(" ") | { "From": .[0], "To": .[1] }]' <<EOF
foo bar
what ever
EOF

[
  {
    "From": "foo",
    "To": "bar"
  }
]
[
  {
    "From": "what",
    "To": "ever"
  }
]

因此,有些麻烦的-n/inputs。注意,inputs需要JQVersion1.5。

票数 3
EN

Stack Overflow用户

发布于 2016-12-11 03:29:29

下面是一个所有jq解决方案,该解决方案假定"From“和"To”值与您的示例完全相同:

代码语言:javascript
复制
jq -R -n '[inputs | split(" ") | {From: .[0], To: .[1]}]'

您可能希望使用gsub/2处理其他空间。

如果您的jq没有inputs,那么您可以使用以下咒语:

代码语言:javascript
复制
jq -R -s 'split("\n")
  | map(select(length>1) | split(" ") | {From: .[0], To: .[1]})'

或者,您可以将时间循环的输出输送到jq -s中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41082241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档