【问题标题】:How do I merge thousands of json files with jq?如何将数千个 json 文件与 jq 合并?
【发布时间】:2021-06-21 05:35:39
【问题描述】:

我在单个 windows 目录中有数千个单独命名的 json 文件。我正在尝试使用 jq 将它们全部合并到一个文件中,然后我可以导入到 jupyter 笔记本中。

当我尝试运行以下命令时,我不断收到许可被拒绝错误:

jq --slurp 'map(.[])' bill

我已尝试编辑目录 (bill) 权限。我的文件路径如下所示:

\downloadedJSONfiles\AK\2019-2020_31st_Legislature\bill

我通过chocolately 下载了jq。我正在使用cmder

【问题讨论】:

  • 您可以使用bill/* 或将目录更改为bill 并使用* 代替bill
  • 与其创建怪物JSON,是否可以使用PyPi的jsonlines(pypi.org/project/jsonlines)?

标签: json windows cmd jq cmder


【解决方案1】:

您的权限被拒绝,因为您提供了一个预期普通文件路径的目录。


我将从“unix”方法开始,因为 jq 具有 unix 根源。以下是您要使用的命令:

jq --slurp 'map(.[])' bill/a.json bill/b.json bill/c.json ...

shell 会将以下命令扩展为上面的:

jq --slurp 'map(.[])' bill/*.json

问题在于,这很容易导致命令过长。所以你真的想要以下之一:

# A
(
   jq '.[]' bill/a.json
   jq '.[]' bill/b.json
   jq '.[]' bill/c.json
   jq '.[]' bill/d.json
   jq '.[]' bill/e.json
   jq '.[]' bill/f.json
) | jq --slurp .
# B
(
   cat bill/a.json
   cat bill/b.json
   cat bill/c.json
   cat bill/d.json
   cat bill/e.json
   cat bill/f.json
) | jq --slurp 'map(.[])'
# C
(
   jq '.[]' bill/a.json bill/b.json bill/c.json
   jq '.[]' bill/d.json bill/e.json bill/f.json
) | jq --slurp .
# D
(
   cat bill/a.json bill/b.json bill/c.json
   cat bill/d.json bill/e.json bill/f.json
) | jq --slurp 'map(.[])'

使用以下任何一种方法都可以实现等效:

# Portable. Equivalent to A
find bill -mindepth 1 -maxdepth 1 -name '*.json' -exec jq '.[]' {} \; | jq --slurp .
# Portable. Equivalent to B
find bill -mindepth 1 -maxdepth 1 -name '*.json' -exec cat {} \; | jq --slurp 'map(.[])'
# Possibly portable with tweaks. Similar to "C"
find bill -mindepth 1 -maxdepth 1 -name '*.json' -print0 |
   xargs -r0 jq '.[]' |
      jq --slurp .
# Possibly portable with tweaks. Similar to "D"
find bill -mindepth 1 -maxdepth 1 -name '*.json' -print0 |
   xargs -r0 cat |
      jq --slurp .
# GNU-specific. Equivalent to "C"
find bill -mindepth 1 -maxdepth 1 -name '*.json' -exec jq '.[]' {} + | jq --slurp .
# GNU-specific. Equivalent to "D"
find bill -mindepth 1 -maxdepth 1 -name '*.json' -exec cat {} + | jq --slurp 'map(.[])'

但是您询问了 Windows。在 Windows 世界中,由程序执行自己的通配符扩展。所以你希望能够做到

jq --slurp 'map(.[])' bill\*.json

但是,jq 没有正确移植。

Assertion failed!

Program: c:\bin\jq.exe
File: src/main.c, Line 256

Expression: wargc == argc

因此,就像在 unix 中一样,您必须将要处理的所有文件作为单独的参数传递给 jq

使用cmd,您可以使用以下任意一种:

:: Not efficient
copy /y nul bill.jsonl
for %q in (bill\*.json) do jq ".[]" %q >>bill.jsonl
jq --slurp . bill.jsonl
del bill.jsonl
:: More efficient
copy /y nul+bill\*.json bill.jsonl
jq --slurp "map(.[])" bill.jsonl
del bill.jsonl

PowerShell 是一个比cmd 先进得多的shell。使用 PowerShell,您可以使用

jq --slurp 'map(.[])' ( Get-Item bill\*.json )

但是就像简单的 unix 版本一样,上面很容易导致命令行太长。为避免这种情况,我们可以使用以下方法:

# Not efficient
Get-Item bill\*.json | %{ jq '.[]' $_ } | jq --slurp .
# More efficient
Get-Item bill\*.json | %{ Get-Content $_ } | jq --slurp 'map(.[])'

%{...}ForEach-Object {...} 的简写。)


最后,我对 Cmder 不熟悉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    相关资源
    最近更新 更多