有没有办法从python

时间:2016-07-06 09:16:55

标签: python arrays json jq

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

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

基本上我试图使用jq从JSON中提取数据。由于JSON包含嵌套数组,我必须使用变量循环。

我的问题是 -

  • 我可以从python脚本执行此命令吗
  • 如果可以,那么我将如何遍历嵌套数组
  • 示例数据中的元素给出了上述(address [] [] .street)

我不想使用除python之外的任何语言,因为它会导致兼容性问题。

6 个答案:

答案 0 :(得分:11)

来自jq FAQ

  

问:Python可以使用哪些绑定?

     

A:

     

pip install jq#有关详细信息,请参阅https://pypi.python.org/pypi/jq

     

pip install pyjq#有关详细信息,请参阅https://pypi.python.org/pypi/pyjq

对于你的嵌套数组,循环遍历它听起来像是可以(也许应该)在jq中完成的事情。

答案 1 :(得分:3)

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

    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. 如果可以,那么我将如何遍历嵌套数组 样本数据中的元素给出上述(address [] [] .street)
    2. 查看包含少量记录的JSON数据集会有所帮助。对于使用jq循环遍历python中的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())
      

      享受!

答案 2 :(得分:3)

sh模块可以轻松地从python调用jq子进程。 e.g。

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

答案 3 :(得分:3)

我相信公认的答案应该是Peak的答案,因为在python中使用C api的正确方法是通过python绑定库,并且https://pypi.python.org/pypi/jqhttps://pypi.python.org/pypi/pyjq都应能按预期工作。 / p>


话虽这么说,由于我们正在谈论python,所以我想提出一个更具有pythonic的替代方法: glom pip install glomhttps://glom.readthedocs.io/

使用jq而不是像glom中那样使用DSL,您只需使用纯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)

答案 4 :(得分:2)

嗯,我是jq的忠实粉丝,但看起来你似乎并没有做过一些在Python中也不容易做到的事情。考虑:

import json

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

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

答案 5 :(得分:0)

是的。使用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作为查询语言。