使用命令行工具将JSON数组拆分为多个文件

Eme*_*mer 4 bash json split jq

假设我们有一个长度为5的JSON数组,我们想使用linux命令行工具将该数组拆分为多个长度为2的数组,并将分组的项目保存到不同的文件中。

我使用jqsplit工具进行了尝试(对于可以从bash脚本执行的任何方法,我都很满意):

$ echo '[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"},{"key4":"value4"},{"key5":"value5"}]' | jq -c -M '.[]' | split -l 2 -d -a 3 - meta_
$ tail -n +1 meta_*
==> meta_000 <==
{"key1":"value1"}
{"key2":"value2"}

==> meta_001 <==
{"key3":"value3"}
{"key4":"value4"}

==> meta_002 <==
{"key5":"value5"}
Run Code Online (Sandbox Code Playgroud)

前面的命令将项目正确保存到文件中,但是我们需要将它们转换为有效的JSON数组格式。我对--filter选项感到厌倦:

$ echo '[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"},{"key4":"value4"},{"key5":"value5"}]' | jq -c -M '.[]' | split -l 2 -d -a 3 - meta2_ --filter='jq --slurp -c -M'
[{"key1":"value1"},{"key2":"value2"}]
[{"key3":"value3"},{"key4":"value4"}]
[{"key5":"value5"}]
$ tail -n +1 meta2_*
tail: cannot open 'meta2_*' for reading: No such file or directory
Run Code Online (Sandbox Code Playgroud)

但是,它会在屏幕上显示输出,但结果不会持续存在。我尝试转发输出,但出现错误:

echo '[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"},{"key4":"value4"},{"key5":"value5"}]' | jq -c -M '.[]' | split -l 2 -d -a 3 - meta2_ --filter='jq --slurp -c -M > $FILE'
...
split: with FILE=meta2_000, exit 2 from command: jq --slurp -c -M > $FILE
Run Code Online (Sandbox Code Playgroud)

有什么提示或更好的方法吗?

编辑:我尝试用双引号@andlrc建议:

$ echo '[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"},{"key4":"value4"},{"key5":"value5"}]' | jq -c -M '.[]' | split -l 2 -d -a 3 - meta2_ --filter="jq --slurp -c -M > $FILE"
bash: -c: line 0: syntax error near unexpected token `newline'
bash: -c: line 0: `jq --slurp -c -M > '
split: with FILE=meta2_000, exit 1 from command: jq --slurp -c -M >
$ cat meta_000 | jq --slurp -c -M
[{"key1":"value1"},{"key2":"value2"}]
Run Code Online (Sandbox Code Playgroud)

Jef*_*ado 5

在jq过滤器中构建数组,然后每行拆分为文件会更容易。无需其他过滤。

range(0; length; 2) as $i | .[$i:$i+2]
Run Code Online (Sandbox Code Playgroud)

产生:

[{"key1":"value1"},{"key2":"value2"}]
[{"key3":"value3"},{"key4":"value4"}]
[{"key5":"value5"}]
Run Code Online (Sandbox Code Playgroud)

因此,将它们放在一起。

$ jq -cM --argjson sublen '2' 'range(0; length; $sublen) as $i | .[$i:$i+$sublen]' \
    input.json | split -l 1 -da 3 - meta2_
Run Code Online (Sandbox Code Playgroud)


Cha*_*ffy 0

分成两个单独的jq调用允许第二个调用使用input帮助器一次仅处理单个输入。try如果您没有剩下两项输入,那么在第二个中使用助手可以让它优雅地处理不完整的行。


s='[{"key1":"value1"},{"key2":"value2"},{"key3":"value3"},{"key4":"value4"},{"key5":"value5"}]'

jq '.[]' <<<"$s" | \
  jq -c -n 'repeat(input as $i1 | try (input as $i2 | [$i1, $i2]) catch [$i1])?' | \
  split -l 2 -d -a 3 - meta_
Run Code Online (Sandbox Code Playgroud)

...在第一个文件中发出:

[{"key1":"value1"},{"key2":"value2"}]
[{"key3":"value3"},{"key4":"value4"}]
Run Code Online (Sandbox Code Playgroud)

...并且,在第二个中:

[{"key5":"value5"}]
Run Code Online (Sandbox Code Playgroud)