我需要从文件中读取 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
转换为数组(或除单个对象之外的任何其他结构),它将提前终止。