pythonスクリプトからjqコマンドを実行しようとしています。現在、ターミナル(MacO)から実行すると、jqコマンドは正常に動作しています。
cat filename.json |jq '{Name:.name, address:.address[0][1].street}'
基本的に私はjqを使用してJSONからデータを抽出しようとしています。 JSONにはネストされた配列が含まれているため、変数を使用してループする必要があります。
私の質問は-
互換性の問題が発生するため、Python以外の言語を使用したくありません。
Jqから [〜#〜] faq [〜#〜] :
Q:Pythonで使用できるバインディングは何ですか?
A:
pip install jq#詳細については、 https://pypi.python.org/pypi/jq を参照してください
pip install pyjq#詳細は、 https://pypi.python.org/pypi/pyjq を参照してください
ネストされた配列については、それをループすることは、jq内で実行できる(そしておそらく実行する必要がある)もののように聞こえます。
pythonでC apiを使用する適切な方法はpythonバインディングライブラリ、およびその両方を経由するため、受け入れられた答えはピークの答えである必要があります- https://pypi.python.org/pypi/jq および https://pypi.python.org/pypi/pyjq は期待どおりに機能するはずです。
そうは言っても、私たちはpythonについて話しているので、私はもっとPythonicである代替をもたらしたいと思います:glom(pip install glom
、 https://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)
sh
モジュールを使用すると、Pythonからjqサブプロセスを簡単に呼び出すことができます。例えば.
import sh
cmd = sh.jq('-M', '{Name:.name, address:.address[0][1].street}', 'filename.json')
print "cmd returned >>%s<<" % cmd.stdout
まあ、私はjqの大ファンですが、Python=でも簡単に実行できないことをしているようには見えません。考慮してください。
import json
with open("filename.json", "r") as f:
data = json.load(f)
{"Name": data["name"], "address": data["address"][0][1]["street"]}
はい、サブプロセスを使用します。例:
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()
いくつかのレコードを含むJSONデータセットを表示すると役立ちます。 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())
楽しい!