项目作者: podhmo

项目描述 :
jq for pythonista
高级语言: Python
项目地址: git://github.com/podhmo/jqfpy.git
创建时间: 2017-08-26T06:20:44Z
项目社区:https://github.com/podhmo/jqfpy

开源协议:MIT License

下载


jqfpy

Build Status

jq is too difficult

jq is too difficult, at least for me.

For example, extracting key-name when use is true only, from below JSON data.

  1. {
  2. "apps": {
  3. "foo": {
  4. "use": true
  5. },
  6. "bar": {
  7. "use": true
  8. },
  9. "boo": {
  10. "use": true
  11. },
  12. "bee": {
  13. "use": false
  14. }
  15. }
  16. }

What is jq’s answer? (taking over 30 minutes, my past challenges).

  1. $ cat data.json | jq '.apps | . as $$o | keys | map(select($$o[.].use))'
  2. [
  3. "bar",
  4. "boo",
  5. "foo"
  6. ]

If you have python’s knowledge, this is tiny oneliner, isn’t it?

  1. $ cat data.json | jqfpy '[k for k, opts in get("apps").items() if opts["use"]]'
  2. [
  3. "foo",
  4. "bar",
  5. "boo"
  6. ]

(get() is special function, like a json.load(sys.stdin).get.)

install

  1. $ pip install jqfpy

how to use

describe syntax

todo.

tutorial

this is jqfpy version of jq’s Tutorial

  1. $ alias jsonDATA="curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'"
  2. # jq.
  3. $ jsonDATA | jq '.'
  4. # jqfpy.
  5. $ jsonDATA | jqfpy 'get()'
  1. # jq.
  2. $ jsonDATA | jq '.[0]'
  3. # jqfpy.
  4. $ jsonDATA | jqfpy 'get()[0]'
  1. # jq.
  2. $ jsonDATA | jq '.[0] | {message: .commit.message, name: .commit.committer.name}'
  3. # jqfpy.
  4. $ jsonDATA | jqfpy 'd = get()[0]; {"message": get("commit/message", d), "name": get("commit/committer/name", d)}'
  5. # or
  6. $ jsonDATA | jqfpy '{"message": get("0/commit/message"), "name": get("0/commit/committer/name")}'
  1. # jq.
  2. $ jsonDATA | jq '.[] | {message: .commit.message, name: .commit.committer.name}'
  3. # jqfpy.
  4. $ jsonDATA | jqfpy --squash 'L = get(); [{"message": get("commit/message", d), "name": get("commit/committer/name", d)} for d in L]'
  1. # jq.
  2. $ jsonDATA | jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'
  3. # jqfpy.
  4. $ jsonDATA | 'L = get(); [{"message": get("commit/message", d), "name": get("commit/committer/name", d), "parents": [p["html_url"] for p in d["parents"]]} for d in L]'
  5. # or (using h.pick)
  6. $ jsonDATA | 'L = get(); [h.pick("commit/message@message", "commit/committer/name@name", "parents[]/html_url@parents", d=d) for d in L]'

additionals

other formats support

jqfpy is supporting other formats(but this is experimental feature)

  • yaml
  • ltsv

if you want to use yaml supported version. install via below command.

  1. $ pip install jqfpy[yaml]

and calling jqfpy with --input-format,-i option and --output-format,-o option.

02data.yaml

  1. person:
  2. name: foo
  3. age: 20
  4. nickname: fool
  1. $ cat 02data.yaml | jqfpy -i yaml 'get("person")'
  2. {
  3. "name": "foo",
  4. "age": 20,
  5. "nickname": "fool"
  6. }
  7. $ cat 02data.yaml | jqfpy -i yaml -o ltsv 'get("person")'
  8. name:foo age:20 nickname:fool

helper functions

helper functions are included.

  • pick()
  • omit()
  • flatten()
  • chunk()
  • loadfile()
  • dumpfile()

pick()

  1. $ cat 02data.yaml | jqfpy -i yaml 'h.pick("person/name", "person/age")'
  2. {
  3. "person": {
  4. "name": "foo",
  5. "age": 20
  6. }
  7. }
  8. $ cat 02data.yaml | jqfpy -i yaml 'h.pick("person/name@name", "person/age@age")'
  9. {
  10. "name": "foo",
  11. "age": 20
  12. }

omit()

  1. $ cat 02data.yaml | jqfpy -i yaml 'h.omit("person/nickname")'
  2. {
  3. "person": {
  4. "name": "foo",
  5. "age": 20
  6. }
  7. }

flatten()

  1. $ seq 1 5 | jqfpy --slurp -c 'L = get(); [L, L]'
  2. [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
  3. $ seq 1 5 | jqfpy --slurp -c 'L = get(); h.flatten([L, L], n=1)'
  4. [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

chunk()

  1. $ seq 1 10 | jqfpy --slurp -c 'h.chunk(get(), n=3)'
  2. [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

loadfile()

  1. $ ls *.json
  2. a.json b.json
  3. $ echo '["a", "b"]' | jqfpy '{name: h.loadfile(f"{name}.json") for name in get()}'

--here and --relative-path options.

  1. # see ./x.json
  2. $ jqfpy 'h.loadfile("x.json")' a/b/main.json
  3. # see ./a/b/x.json
  4. $ jqfpy --here a/b/ 'h.loadfile("x.json")' a/b/main.json
  5. # see ./a/b/x.json
  6. $ jqfpy --relative-path 'h.loadfile("x.json")' a/b/main.json

dumpfile()

  1. $ echo {"person0.json": {"name": "foo", "age": 20}, "person1.json": {"name": "bar}} | jqfpy '[h.dumpfile(v, fname) for fname, v in get().item()]' > /dev/null

individual helper module with —additionals

match.py

  1. import re
  2. def match(rx, text):
  3. if text is None:
  4. return False
  5. return re.search(rx, text)
  1. $ cat examples/additionals/00data.json | jqfpy --additionals=./match.py '[d for d in get("constraint") if h.match("^1\..+", d.get("version"))]'
  2. [
  3. {
  4. "name": "github.com/Masterminds/vcs",
  5. "version": "1.11.0"
  6. },
  7. {
  8. "name": "github.com/boltdb/bolt",
  9. "version": "1.0.0"
  10. }
  11. ]