shell中如何将多个json对象合并到一个json数组中

shell中如何将多个json对象合并到一个json数组中

我需要从文件中读取 json 数据的某些字段以组成新的 json 列表。该文件是由生成的reading data from multiple servers via pssh

# pssh_result.txt
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13",...}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23",...}
...
...

我目前只能从中提取字段,但我不知道如何将它们组合成完成的 json 数组

#!/bin/sh
input="pssh_result.txt"
while IFS= read -r line; do
    # echo "$line"
    if jq -e . >/dev/null 2>&1 <<<"$line"; then
        read field1 field3 <<<$(echo $(echo $line |
            jq -r '.field1, .field3'))
        example_item=$(jq --null-input \
            --arg field1 "$field1" \
            --arg field3 "$field3" \
            '{"alias1": $field1, "alias2": $field3}')

        echo $example_item
    fi
done <"$input"

输出如下

sh test.sh 
{ "alias1": "value11", "alias2": "value13" }
{ "alias1": "value21", "alias2": "value23" }

但是我要合并将其放入一个大的 json 数组中,以便稍后发送给第三方进行处理,并且期望的结果如下

[
    {
        "alias1": "value11",
        "alias2": "value13"
    },
    {
        "alias1": "value21",
        "alias2": "value23"
    }
]

我还考虑过将其放入数组中,然后将其传递给类似的东西join(arr,","),但它没有按预期工作。

我怎样才能得到我想要的结果?我真的很感谢对此的任何帮助。

答案1

假设输入看起来像

[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}

(请注意,我已修复了包含 JSON 对象的行上损坏的 JSON。)

...然后您可以使用以下命令提取所需的行grep

grep '^{' file

或者

grep -v -F '[SUCCESS]' file

或类似的grep命令。

然后,您可以使用 解析 JSON 对象流jq -s,它会自动将它们读入数组。这允许您像这样处理数据:

grep '^{' file | jq -s 'map({ alias1: .field1, alias2: .field3 })'

使用上面显示的输入file,这将生成

[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

如果您对更改现有的初始输入解析不感兴趣,并且希望将输出放入数组中,那么只需将其传递即可jq -s .

$ cat file
{ "alias1": "value11", "alias2": "value13" }
{ "alias1": "value21", "alias2": "value23" }
$ jq -s . file
[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

一个值得阅读的黑客直接地从原始文件中jq读取数据作为原始字符串,尝试将它们转换为有效的 JSON,然后丢弃任何错误:

$ cat file
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}
$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null
{
  "alias1": "value11",
  "alias2": "value13"
}
{
  "alias1": "value21",
  "alias2": "value23"
}

然后可以将其收集在一个数组中:

$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null | jq -s .
[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

请注意,我们需要在这里进行两次单独的调用,jq因为如果第一次jq调用尝试将输入转换为 JSON 并fromjson转换为数组(或除单个对象之外的任何其他结构),它将提前终止。

相关内容