我有一个大的JSON文件,它是一个对象中的对象,我想将其拆分为以对象键命名的单独文件。 是否可以使用jq或任何其他现成的工具实现此目的?
原始的JSON格式如下:
{ "item1": {...}, "item2": {...}, ...}
给定这个输入,我想生成文件item1.json、item2.json等。
我有一个大的JSON文件,它是一个对象中的对象,我想将其拆分为以对象键命名的单独文件。 是否可以使用jq或任何其他现成的工具实现此目的?
原始的JSON格式如下:
{ "item1": {...}, "item2": {...}, ...}
给定这个输入,我想生成文件item1.json、item2.json等。
这应该能为你提供一个开始:
for f in `cat input.json | jq -r 'keys[]'` ; do
cat input.json | jq ".$f" > $f.json
done
或者当你坚持更喜欢某些人偏爱的bashy语法时:
for f in $(jq -r 'keys[]') ; do
jq ".[\"$f\"]" < input.json > "$f.json"
done < input.json
cat file | command
是反模式,反引号是另一种。 - RomanPerekhrestjq --arg f "$f" '.[$f]'
将是一个进一步的改进,可以防止任意代码注入(尽管在 jq 获取 system()
调用、打开文件进行写操作或其他当前不支持的功能之前,这并不是一个很大的安全问题),因为它确保被替换的值只能被视为字面字符串。 - Charles Duffyjq -n --argjson f "$f" '$f'
还可以保证良好的解析;如果您不使用管道,则 -n
很重要。 - Thiago Conrado这是一种只需一次调用jq的解决方案:
```jq -cr 'keys[] as $k | "\($k)\n\(.[$k])"' input.json |
while read -r key ; do
read -r item
printf "%s\n" "$item" > "/tmp/$key.json"
done
jq -cr 'keys[] as $k | "\($k)\t\(.[$k])"' input.json |
awk -F\\t '{ print $2 > "/tmp/" $1 ".json" }'
使用jq或其他现成工具,是否可以实现这一点?
是的。xidel 也可以非常高效地完成此任务。
假设'input.json':
{
"item1": {
"a": 1
},
"item2": {
"b": 2
},
"item3": {
"c": 3
}
}
低效的Bash方法:
for f in $(xidel -s input.json -e '$json()'); do
xidel -s input.json -e '$json("'$f'")' > $f.json
done
xidel
实例来解析该对象。特别是当您有一个非常大的JSON时,这会相当缓慢。file:write()
方法:xidel -s input.json -e '
$json() ! file:write(
.||".json",
$json(.),
{"method":"json"}
)
'
xidel
调用会创建 'item{1,2,3}.json',它们的内容是紧凑/缩小的对象,例如{"a": 1}
是 'item1.json' 的内容。
xidel -s input.json -e '
for $x in $json() return
file:write(
concat($x,".json"),
$json($x),
{
"method":"json",
"indent":true()
}
)
'
一个 xidel
调用会创建 'item{1,2,3}.json'。它们的内容是一个漂亮格式化的对象(因为有 {"indent":true()}
),如下所示...
{
"a": 1
}
...对于'item1.json'。不同的查询(for循环),相同的结果。
这种方法速度快得多!