json 有办法从python执行jq吗

piztneat  于 12个月前  发布在  Python
关注(0)|答案(7)|浏览(140)

我试图从我的python脚本执行jq命令。目前,当我从终端(MacOS)执行时,jq命令工作正常。

cat filename.json |jq '{Name:.name, address:.address[0][1].street}'

字符串
基本上,我试图使用jq从JSON中提取数据。由于JSON包含嵌套数组,我必须使用变量循环。
我的问题是-

  • 我可以从python脚本执行此命令吗
  • 如果可以的话,那么我如何循环遍历嵌套数组呢
  • 样本数据中的元素给予上述(地址[][].street)

我不想使用Python以外的任何语言,因为这会导致兼容性问题。

vs3odd8k

vs3odd8k1#

从jq FAQ
问:Python有哪些绑定可用?
答:
pip install jq #详情请参阅https://pypi.python.org/pypi/jq
pip install pyjq #详情请参阅https://pypi.python.org/pypi/pyjq
至于嵌套数组,循环遍历它听起来像是可以(也许应该)在jq中完成的事情。

2exbekwf

2exbekwf2#

我相信公认的答案应该是peak的答案,因为在python中使用C API的正确方法是通过python绑定库,https://pypi.python.org/pypi/jqhttps://pypi.python.org/pypi/pyjq都应该按预期工作。
话虽如此,既然我们谈论的是Python,我想带来一个更Python的替代方案:glompip install glomhttps://glom.readthedocs.io/
jq中使用的DSL不同,glom只需使用纯python以所需格式声明输出(此输出格式称为spec)。在本例中,您需要一个简单的dict

spec = {'Name': 'name',
        'street': 'address.0.1.street'}

字符串
然后在你的数据上调用glom:

output_data = glom(input_data, spec)


就像jq一样,你也可以在命令行中使用glom

cat filename.json | glom "{'Name': 'name', 'street': 'address.0.1.street'}"


一个完整的python例子:

import json
from pprint import pprint
from glom import glom

with open('filename.json', 'rt') as f:
    input_data = json.load(f)

spec = {'Name': 'name',
        'street': 'address.0.1.street'}

output_data = glom(input_data, spec)

pprint(output_data)

j91ykkif

j91ykkif3#

好吧,我是jq的忠实粉丝,但看起来你也在做一些在Python中无法轻松完成的事情。考虑一下:

import json

with open("filename.json", "r") as f:
    data = json.load(f)

{"Name": data["name"], "address": data["address"][0][1]["street"]}

字符串

wmomyfyw

wmomyfyw4#

sh模块可以很容易地从python调用jq子进程。

import sh
cmd = sh.jq('-M', '{Name:.name, address:.address[0][1].street}', 'filename.json')
print "cmd returned >>%s<<" % cmd.stdout

字符串

z4iuyo4d

z4iuyo4d5#

1.我可以从python脚本执行此命令吗
是,使用子流程。示例:

jsonFile = '/path/to/your/filename.json'
jq_cmd = "/bin/jq '{Name:.name, address:.address[0][1].street}' " + jsonFile
jq_proc = subprocess.Popen(jq_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

# read JSON object, convert to string, store as a dictionary

jDict = json.loads(jq_proc.stdout.read())
jq_proc.stdout.close()

字符串
1.如果可以做到这一点,那么我将如何循环通过嵌套数组元素的样本数据给予以上(地址[][].street)
这将有助于看到一个JSON数据集与一些记录。为了在Python中使用jq循环JSON集,很容易获得对象的计数,然后重新计数。稍微有点开销,但它使代码易于理解。

# count number of JSON records from the root level

jq_cmd = "/bin/jq '. | length' " + jsonFile
jq_proc = subprocess.Popen(jq_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

jObjCount = int(jq_proc.stdout.read())
jq_proc.stdout.close()

# iterate over each root level JSON record

for ix in range(jObjCount):

  jq_cmd = "jq '. | .[" + str(ix) + "]' " + jsonFile 
  jq_proc = subprocess.Popen(jq_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

  # read object, convert to string, store as a python dictionary

  jDict = json.loads(jq_proc.stdout.read())

  # iterate over nested objects within a root level object    
  # as before, count number items but here for each root level JSON object

  jq_cmd = "/bin/jq '. | .[" + str(ix) + "].sub_Item_Key | length' " + jsonFile
  jq_proc = subprocess.Popen(jq_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  jItemCount = int(jq_proc.stdout.read())
  jq_proc.stdout.close()

  for jx in range(jItemCount):

     jq_cmd = "/bin/jq '. | .[" + str(ix) + "].sub_Item_Key[" + str(jx) + "]' " + jsonFile
     jq_proc = subprocess.Popen(jq_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

     # read JSON item, convert to string, store as a python dictionary

     jItemDict = json.loads(jq_proc.stdout.read())


好好享受吧!

nwnhqdif

nwnhqdif6#

是的。使用plumbum

from plumbum.cmd import jq, cat

(cat["filename.json"] | jq ["{Name:.name, address:.address[0][1].street}"])()

字符串
上面命令的结果是一个JSON对象,可以使用json.loads解析为Python对象。
您可能还对jello感兴趣,它类似于jq,但使用Python作为查询语言。

uqdfh47h

uqdfh47h7#

**有一个名为JQpy的JQ Python绑定。**这个绑定不需要用户编译任何东西,因此只适用于Linux。

安装程序
Linux:

sudo apt-get update && sudo apt-get install jq
pip install jqpy

字符串
窗口:

choco install jq
pip install jqpy

示例

>>> from jqpy import jq
>>> jq('.results[] | {age, city}', {
                "timestamp": 1234567890,
                "report": "Age Report",
                "results": [
                        { "name": "John", "age": 43, "city": "TownA" },
                        { "name": "Joe",  "age": 10, "city": "TownB" }
                ]
        })
[{'age': 43, 'city': 'TownA'}, {'age': 10, 'city': 'TownB'}]

原问题

import json, jqpy

# 1. Load JSON data
with open('filename.json','r',encoding='utf8') as f:
    data = json.loads(f)

# 2. Process with JQpy
processed = jqpy.jq('{Name:.name, address:.address[0][1].street}', data)[0]

# 3. Do stuff with outcome
print(f'{processed['Name']=}')

相关问题