Git Product home page Git Product logo

yq's Introduction

yq: Command-line YAML/XML/TOML processor - jq wrapper for YAML, XML, TOML documents

Installation

pip install yq

Before using yq, you also have to install its dependency, jq. See the jq installation instructions for details and directions specific to your platform.

On macOS, yq is also available on Homebrew: use brew install python-yq.

Synopsis

yq takes YAML input, converts it to JSON, and pipes it to jq:

cat input.yml | yq .foo.bar

Like in jq, you can also specify input filename(s) as arguments:

yq .foo.bar input.yml

By default, no conversion of jq output is done. Use the --yaml-output/-y option to convert it back into YAML:

cat input.yml | yq -y .foo.bar

Mapping key order is preserved. By default, custom YAML tags and styles in the input are ignored. Use the --yaml-roundtrip/-Y option to preserve YAML tags and styles by representing them as extra items in their enclosing mappings and sequences while in JSON:

yq -Y .foo.bar input.yml

yq can be called as a module if needed. With -y/-Y, files can be edited in place like with sed -i:

python -m yq -Y --indentless --in-place '.["current-context"] = "staging-cluster"' ~/.kube/config

Use the --width/-w option to pass the line wrap width for string literals. Use --explicit-start/--explicit-end to emit YAML start/end markers even when processing a single document. All other command line arguments are forwarded to jq. yq forwards the exit code jq produced, unless there was an error in YAML parsing, in which case the exit code is 1. See the jq manual for more details on jq features and options.

Because YAML treats JSON as a dialect of YAML, you can use yq to convert JSON to YAML: yq -y . < in.json > out.yml.

Preserving tags and styles using the -Y (--yaml-roundtrip) option

The -Y option helps preserve custom string styles and tags in your document. For example, consider the following document (an AWS CloudFormation template fragment):

Resources:
  ElasticLoadBalancer:
    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
    Properties:
      AvailabilityZones: !GetAZs ''
      Instances:
        - !Ref Ec2Instance1
        - !Ref Ec2Instance2
      Description: >-
        Load balancer for Big Important Service.

        Good thing it's managed by this template.

Passing this document through yq -y .Resources.ElasticLoadBalancer will drop custom tags, such as !Ref, and styles, such as the folded style of the Description field:

Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
  AvailabilityZones: ''
  Instances:
    - Ec2Instance1
    - Ec2Instance2
  Description: 'Load balancer for Big Important Service.

    Good thing it''s managed by this template.'

By contrast, passing it through yq -Y .Resources.ElasticLoadBalancer will preserve tags and styles:

Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
Properties:
  AvailabilityZones: !GetAZs ''
  Instances:
    - !Ref 'Ec2Instance1'
    - !Ref 'Ec2Instance2'
  Description: >-
    Load balancer for Big Important Service.

    Good thing it's managed by this template.

To accomplish this in -Y mode, yq carries extra metadata (mapping pairs and sequence values) in the JSON representation of your document for any custom tags or styles that it finds. When converting the JSON back into YAML, it parses this metadata, re-applies the tags and styles, and discards the extra pairs and values.

yq does not support passing YAML comments into the JSON representation used by jq, or roundtripping such comments.

XML support

yq also supports XML. The yq package installs an executable, xq, which transcodes XML to JSON using xmltodict and pipes it to jq. Roundtrip transcoding is available with the xq --xml-output/xq -x option. Multiple XML documents can be passed in separate files/streams as xq a.xml b.xml. Use --xml-item-depth to descend into large documents, streaming their contents without loading the full doc into memory (for example, stream a Wikipedia database dump with cat enwiki-*.xml.bz2 | bunzip2 | xq . --xml-item-depth=2). Entity expansion and DTD resolution is disabled to avoid XML parsing vulnerabilities. Use python -m yq.xq if you want to ensure a specific Python runtime.

TOML support

yq supports TOML as well. The yq package installs an executable, tomlq, which uses the tomlkit library to transcode TOML to JSON, then pipes it to jq. Roundtrip transcoding is available with the tomlq --toml-output/tomlq -t option. Use python -m yq.tomlq if you want to ensure a specific Python runtime.

Compatibility note

This package's release series available on PyPI begins with version 2.0.0. Versions of yq prior to 2.0.0 are distributed by https://github.com/abesto/yq and are not related to this package. No guarantees of compatibility are made between abesto/yq and kislyuk/yq. This package follows the Semantic Versioning 2.0.0 standard. To ensure proper operation, declare dependency version ranges according to SemVer.

Authors

  • Andrey Kislyuk

Bugs

Please report bugs, issues, feature requests, etc. on GitHub.

License

Licensed under the terms of the Apache License, Version 2.0.

image

image

image

image

yq's People

Contributors

bubbleattic avatar cmeister2 avatar conao3 avatar denis-yuen avatar dprunier avatar hellomello13 avatar jakirkham avatar jakseb avatar kislyuk avatar nohal avatar polyzen avatar sodre avatar thejcannon avatar zmedico avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yq's Issues

Can't load a standard yaml file

I took just a simple yaml and got this error:

$ cat application.yaml | yq .
Traceback (most recent call last):
File "c:\python27\lib\runpy.py", line 174, in run_module_as_main
"main", fname, loader, pkg_name)
File "c:\python27\lib\runpy.py", line 72, in run_code
exec code in run_globals
File "C:\Python27\Scripts\yq.exe_main
.py", line 9, in
File "c:\python27\lib\site-packages\yq_init
.py", line 150, in main
parser.exit(msg.format(program_name, type(e).name, e))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 23: ordinal not in range(128)

yq throws TyperError datetime.datetime on ISOFormat strings in yaml file

the default yaml loader will parse ISOFormat strings and create datetime objects which doesn't jsonify well.


Example:

$ yq --version
usage: yq [-h] [--yaml-output] [--width WIDTH] jq_filter [file [file ...]]
yq: error: too few arguments
$ pip freeze | grep yq
yq==2.1.2
$ yq . sec.yaml
yq: Error while running jq: TypeError: datetime.datetime(2016, 12, 20, 22, 7, 36) is not JSON serializable.
parse error: Unfinished JSON term
$ cat sec.yaml
data:
    thing: 1
    thing2: "stuff"
    datething: 2016-12-20T22:07:36Z
    datethingstr: "2016-12-20T22:07:36Z"

this needs to override the default encoder class.

# isoformat
class DateTimeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()
        return json.json.JSONEncoder.default(self, o)

# usage
json.dumps(..., cls=DateTimeEncoder)

Support ruamel.yaml as a yaml decoder/encoder

https://bitbucket.org/ruamel/yaml is the link to the package's source code repo, it's ruamel.yaml on pypi.

ruamel.yaml is really nice because it can preserve original formatting, meaning comments, and ordering of maps, etc is preserved. If yq could support this as an optional dependency and flag that allows controlling usage, that would be great. I'd even potentially look into implementing it if it doesn't seem too hard.

--from-file positional parameter not passed to jq since 2.3.5

After changes made to passing positional parameters to jq, it looks like --from-file filter is broken and the filter for jq must be defined as the jq_filter of yq. This means you can no longer define filters in a file, which is invaluable for more complex constructs.

Example Setup

Define a filter and some yaml data

[yq] cat filter
.foo
[yq] cat data
foo
  a: 1

2.3.4

Positional arguments are broken

[yq] yq -y --arg a b . data
usage: yq [-h] [--yaml-output] [--width WIDTH] [--version]
          jq_filter [files [files ...]]
yq: error: argument files: can't open 'b': [Errno 2] No such file or directory: 'b'

--from-file without jq_filter works

[yq] yq -y --from-file filter data
a: 1

2.3.5

After changes to positional parameters, the --args example now works

[yq] yq -y --arg a b . data
foo:
  a: 1

...but the --from-file example is broken, returning the --help text with a return code 0.

[yq] yq -y --from-file filter data
usage: yq [options] <jq filter> [YAML file...]
          jq_filter [files [files ...]]

yq: Command-line YAML processor - jq wrapper for YAML documents
...
[yq] echo $?
0

trying to define the call with the self identify filter still fails to work, returning no error message but a return code of 2.

[yq] yq -y --from-file filter . data
[yq] echo $?
2

Preserve comments

This file:

foo: bar
# This is commented out - baz: bazzz

when passed through yq w test.yaml foo newValue, returns:

foo: newValue

One of the main advantages of using YAML over JSON is to be able to put comments into the file. This functionality is lost with current version of yq.

Misleading documentation

Documentation in the main readme suggests using a similar syntax to JQ, but the basic example doesn't seem to work:

cat input.yml | yq .foo.bar

On OSX:

$ brew install yq
$ cat > input.yml
foo:
 - bar: "text"
   value: 200
baz:
 - bar: "blah"
   value: 100
^D
$ cat ./input.yml | yq .foo.bar
Error: unknown command ".foo.bar" for "yq"
Run 'yq --help' for usage.
2019/04/12 16:18:29 unknown command ".foo.bar" for "yq"

Allow streams of YAML documents as input

Hi!
I am finding yq very useful, but there is one thing that would make it better.
YAML is a superset of JSON, so I imagined that yq's input format would be a superset of jq's input format. However, this turns out not to be true because yq only parses a single YAML object and raises an error if there are multiple objects as input.

For example, if I run this command:

echo \"Hi\" | jq '{ hey: . }, { ho: . }' | yq . -y

I get the following output:

yq: Error running jq: ParserError: expected '<document start>', but found '{'
  in "<stdin>", line 4, column 1.

However, I'd expect to see the following output:

- hey: Hi
- ho: Hi

Is this something you are interested in supporting?

(edit: I realise that piping jq into yq is pointless. My actual use case is that I am developing a tool which outputs data as a JSON stream, and I would like to be able to pipe its output directly into yq . -y to convert it back to YAML and optionally run some jq filters on it. I can achieve this already by piping the ouptut to jq -s '[ . ]' | yq .[] -y but it would be nice if I could just use yq . -y in place of that)

Not able to append to array

I'm using ZSH - hence I need to escape the square brackets

yq w package.yaml dependencies\[+\] "new thing"
usage: yq [-h] [--yaml-output] [--width WIDTH] [--version]
          jq_filter [files [files ...]]
yq: error: argument files: can't open 'dependencies[+]': [Errno 2] No such file or directory: 'dependencies[+]'

package.yaml

name:                app
version:             0.1.0.0
license:             BSD3
license-file:        LICENSE
author:              CabalSaneDefault
maintainer:          nobody
build-type:          Simple
extra-source-files:  ChangeLog.md

dependencies:
  - base >=4.10 && <4.11
  - optparse-applicative
  - process

executable:
  main:             Main.hs
  source-dirs: src

Convert JSON to YAML

JSON should be supported as an input format. My project(s) use YAML internally, but a lot of the external data they source comes in from JSON formats. Considering that it gets processed with yq anyway and yq is making a round trip to JSON, it seems kind of silly that there isn't an --json-input or similar flag to bypass the first half of the round trip. This would allow yq to work as a JSON→YAML conversion tool, reducing my project dependencies.

Streaming pull parsing

from xml.etree import ElementTree as ET
parser = ET.XMLPullParser()

with open(input_filename) as fh:
    i = 0
    while True:
        i += 1
        parser.feed(fh.read(1024*1024))
        for event, element in parser.read_events():
            element.clear()
            del element
        if i % 10 == 0:
            print(i)

Slurp doesn't slurp

It was my assumption that slurping multiple inputs should work the same as in jq, but it does not. For example this works:

echo '{ "one": 1 }\n{ "two": 2 }' | jq -s .

But this fails to parse past the first object:

echo '{ "one": 1 }\n{ "two": 2 }' | yq -s .

You can workaround using jq as an intermediary to slurp into array, then pass to yq and strip off the extra array:

echo '{ "one": 1 }\n{ "two": 2 }' | jq -s . | yq -s .[0]

Conversion between JSON & YAML is broken in some cases

Hi

I've found strange bug where in some scenarios, valid JSON isn't converted back to valid YAML. My use case was to replace a yaml block in one file with a yaml block from another file.
My command was like this:

yq -y ".spec.jobTemplate.spec.template = $(yq '.spec.template' file_b.yaml)" file_a.yaml

Without the -y flag I get valid JSON but if I add the -y flag to output yaml, a new line is being inserted where it shouldn't be causing broken YAML.

Here is a snippet of the outputted JSON:

"args": [
  "/bin/bash",
  "-c",
  "cp -v -r -L /etc/gitlab/.s3cfg $HOME/.s3cfg && while sleep 3600; do :; done"
],

And when I add the -y flag I get this YAML:

args:
- /bin/bash
- -c
- cp -v -r -L /etc/gitlab/.s3cfg $HOME/.s3cfg && while sleep 3600; do
  :; done

It's added a new line inside that last array element.

Values with custom tags are set to `null`

So I have an ansible playbook which has tags like this:

some_key: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  37663434363236326231303035313330356563343734393664373764333962663539623031346531
  6335383361386661613563386265326264613738353632310a633162393366636362633835633430
  34313038633233646432646335643336643234613133643734303530616137366132313038343035
  3039313262386130350a626364633935643562376366306631626530663037376630613565373164
  6261

When trying to extract this, to pipe it into a decrypt:

$ yq '.some_key' file.yml
null

It would be more useful to just ignore tags that aren't recognised and pull the value out as-is, rather than just nulling the value out entirely. It might be a trivial to expose tags separately if you need them?

$ yq --tags '.some_key' file.yml
[
  "vault"
]

Does not seem to support --arg flag

Been trying the following:

cat file.yml | yq --arg foo bar '.metadata.name = $foo'

And I get the following error:

yq: error: argument files: can't open 'bar': [Errno 2] No such file or directory: 'bar'

It would seem that jq's expected syntax for setting args with a space between key and value is tripping things up.

--slurp doesn't work since 2.3.5

If I try to use --slurp with yq, it gets incorrectly translated into --slurpfile. I am using Python 3.5.3.

> touch 2.yaml 3.yaml
> sudo pip3 install yq==2.3.4
> echo | yq -e --slurp '.[0] == .[1]' - 2.yaml 3.yaml
true
> sudo pip3 install yq==2.6.0
> echo | yq -e --slurp '.[0] == .[1]' - 2.yaml 3.yaml
jq: Bad JSON in --slurpfile .[0] == .[1] -: Could not open -: No such file or directory

This is linked to ArgumentParser's prefix matches as described in this SO question.

Workaround: use -s instead of --slurp.

Updates for jq 1.6 compatibility

Given input files such as file.txt:

string from file

f.json:

{ "foo": "bar" }

and f.yaml:

foo: bar

The following command works fine in jq:

❯ jq -M -e -r --rawfile varname file.txt '[$varname, .foo]' -- f.json
[
  "string from file\n",
  "bar"
]

But the following fails in yq:

❯ yq -M -e -r --rawfile varname file.txt '[$varname, .foo]' -- f.yaml
usage: yq [-h] [--yaml-output] [--width WIDTH] [--version]
          jq_filter [files [files ...]]
yq: error: argument files: can't open '[$varname, .foo]': [Errno 2] No such file or directory: '[$varname, .foo]'

Test failure - AssertionError: 2 != 'yq: Error running jq: BrokenPipeError: [Errno 32] Broken pipe.'

 * python3_4: running distutils-r1_run_phase python_test
[
  "2016-12-20T22:07:36"
]
"2016-12-20"
..40333
x"bar"
.{
  "foo": null
}
.{}
3
1
.{}
jq: --indent takes a number between -1 and 7
Use jq --help for help with command-line options,
or see the jq manpage, or online docs  at https://stedolan.github.io/jq
F.
======================================================================
FAIL: test_yq_arg_passthrough (__main__.TestYq)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./test/test.py", line 41, in run_yq
    main(args, input_format=input_format)
  File "/var/tmp/portage/app-misc/yq-2.6.0/work/yq-2.6.0/yq/__init__.py", line 155, in main
    exit(jq.returncode)
SystemExit: 2

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./test/test.py", line 72, in test_yq_arg_passthrough
    self.run_yq("{}", ["--indent", "9", "."], expect_exit_code=err)
  File "./test/test.py", line 43, in run_yq
    self.assertEqual(e.code, expect_exit_code)
AssertionError: 2 != 'yq: Error running jq: BrokenPipeError: [Errno 32] Broken pipe.'

----------------------------------------------------------------------
Ran 8 tests in 0.203s

FAILED (failures=1, expected failures=1)

ExpatError: not well-formed

Hello, I am receiving the following error when trying the XML output. What am I doing wrong?

yq: Error running jq: ExpatError: not well-formed (invalid token): line 1, column 0.

Simple test to json

echo '{"example": "test"}' | yq .
{
  "example": "test"
}

Simple test to xml

echo '{"example": "test"}' | xq -x .
yq: Error running jq: ExpatError: not well-formed (invalid token): line 1, column 0.

I have tried many different files but nothing compiles to xml.

# pip freeze yq
asn1crypto==0.24.0
certifi==2018.4.16
cffi==1.11.5
chardet==3.0.4
cryptography==2.2.2
idna==2.6
Jinja2==2.10
jq==0.1.6
jsonnet==0.10.0
jsonschema==2.6.0
kapitan==0.16.10
MarkupSafe==1.0
pkg-resources==0.0.0
pycparser==2.18
pyparsing==2.2.0
python-gnupg==0.4.2
PyYAML==3.12
reclass==1.5.2
requests==2.18.4
six==1.11.0
ujson==1.35
urllib3==1.22
xmltodict==0.11.0
yq==2.6.0

Tilde character `~` wrong behavior

echo "aaa: 1" | yq ".aaa=\"abc\"" --yaml-output outputs aaa: abc and it is correct.

but if we use ~:
echo "aaa: 1" | yq ".aaa=\"~\"" --yaml-output outputs aaa: '~' which is incorrect.
Expected output is aaa: ~ - without quotation

Color output of keys and values like jq

Awesome project! I'm dealing now with a lot of yml files to be processed in kubernetes...

Is there a way to parse and print the key values in color?

Maybe just the same colors as jq or like in the vim editor?

screen shot 2018-01-26 at 12 51 27 am

xq --xml-output not preserving xml declaration

I have an test.xml file which contains <?xml version="1.0" encoding="UTF-8" standalone="no"?> at its first line.

When I run xq --xml-output '.' test.xml, the generated xml doesn't contain <?xml version="1.0" encoding="UTF-8" standalone="no"?>.

It is possible to modify xq so that it preserves the XML declaration?

No man entry

man yq No manual entry for yq

I would suggest a man entry.

How do I query for fields with dashes in them?

I have the following yaml file foo.yaml:

echo

Now, trying yq .bar.some-data foo.yaml or yq .bar['some-data'] foo.yaml doesn't give me y, but errors:

$ yq .bar.some-data foo.yaml
jq: error: data/0 is not defined at <top-level>, line 1:
.bar.some-data
jq: 1 compile error

$ yq .bar['some-data'] foo.yaml
jq: error: some/0 is not defined at <top-level>, line 1:
.bar[some-data]
jq: error: data/0 is not defined at <top-level>, line 1:
.bar[some-data]
jq: 2 compile errors

What is the correct way to query for those properties?

Tests fail: SyntaxError: unknown encoding: uft-8

On FreeBSD with python-3.6:

Installed /usr/ports/textproc/yq/work/yq-2.7.2/.eggs/wheel-0.33.4-py3.6.egg
running egg_info
writing yq.egg-info/PKG-INFO
writing dependency_links to yq.egg-info/dependency_links.txt
writing entry points to yq.egg-info/entry_points.txt
writing requirements to yq.egg-info/requires.txt
writing top-level names to yq.egg-info/top_level.txt
reading manifest file 'yq.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'yq.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "setup.py", line 46, in <module>
    "Topic :: Software Development :: Libraries :: Python Modules"
  File "/usr/local/lib/python3.6/site-packages/setuptools/__init__.py", line 145, in setup
    return distutils.core.setup(**attrs)
  File "/usr/local/lib/python3.6/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/local/lib/python3.6/distutils/dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "/usr/local/lib/python3.6/distutils/dist.py", line 974, in run_command
    cmd_obj.run()
  File "/usr/local/lib/python3.6/site-packages/setuptools/command/test.py", line 228, in run
    self.run_tests()
  File "/usr/local/lib/python3.6/site-packages/setuptools/command/test.py", line 250, in run_tests
    exit=False,
  File "/usr/local/lib/python3.6/unittest/main.py", line 94, in __init__
    self.parseArgs(argv)
  File "/usr/local/lib/python3.6/unittest/main.py", line 141, in parseArgs
    self.createTests()
  File "/usr/local/lib/python3.6/unittest/main.py", line 148, in createTests
    self.module)
  File "/usr/local/lib/python3.6/unittest/loader.py", line 219, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/local/lib/python3.6/unittest/loader.py", line 219, in <listcomp>
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/local/lib/python3.6/unittest/loader.py", line 190, in loadTestsFromName
    return self.loadTestsFromModule(obj)
  File "/usr/local/lib/python3.6/site-packages/setuptools/command/test.py", line 54, in loadTestsFromModule
    tests.append(self.loadTestsFromName(submodule))
  File "/usr/local/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
    module = __import__(module_name)
  File "/usr/local/lib/python3.6/test/bad_coding.py", line 0
SyntaxError: unknown encoding: uft-8
*** Error code 1

Preserve a YAML 'literal block' (using |), or a 'folded block' (using '>')

yq -y needs to preserve a 'literal block' (using |), or a 'folded block' (using '>')

Original YAML

$ cat y
some:
  file: |
    hello world
    line1
    line2

yaml 2 yaml

It gives different output:

$ cat y | yq -y .
some:
  file: 'hello world

    line1

    line2

    '

Would it be possible to preserve the original YAML 1-1 when yq is instructed to output YAML ?

unexpected keyword argument 'allow_abbrev'

Hello. I get this error everytime I try to launch yq with or without arguments (also the examples in in README.md don't work).

Traceback (most recent call last):
  File "/usr/bin/yq", line 11, in <module>
    load_entry_point('yq==2.7.2', 'console_scripts', 'yq')()
  File "/usr/lib/python3.7/site-packages/yq/__init__.py", line 119, in main
    parser = get_parser(program_name)
  File "/usr/lib/python3.7/site-packages/yq/__init__.py", line 96, in get_parser
    parser = Parser(**parser_args)
TypeError: __init__() got an unexpected keyword argument 'allow_abbrev'

yq does not install. Does not show up on the file system after pip install yq

yq will not install. See below

[root@aks-bastion01-poc /]# pip install yq
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting yq
  Using cached https://files.pythonhosted.org/packages/5c/2e/1df0a8163e19d3699fb745d56ff7d4c8fb0cbfe1d123609dc13dff6170b3/yq-2.7.2-py2.py3-none-any.whl
Requirement already satisfied: xmltodict>=0.11.0 in /usr/lib/python2.7/site-packages (from yq) (0.11.0)
Requirement already satisfied: setuptools in /usr/lib/python2.7/site-packages (from yq) (0.9.8)
Collecting PyYAML>=3.11 (from yq)
  Using cached https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz
Installing collected packages: PyYAML, yq
  Found existing installation: PyYAML 3.10
Cannot uninstall 'PyYAML'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
[root@aks-bastion01-poc /]# yq
-bash: yq: command not found
[root@aks-bastion01-poc /]# find . -name yq 
[root@aks-bastion01-poc /]# 

Add output stream option for library usage

yq internals are not intended to be used as a library, as it dumps out to sys.stdout.

It would be useful to have the output stream of jq provided to the caller, so that another Python module can decide what to do with the data.

Support YAML with multiple docs

The YAML standard allows embedding multiple YAML documents into one by separating them with --- lines.

When yq is given these as input, it errors out with:

yq: Error while running jq: ComposerError: expected a single document in the stream
  in "<stdin>", line 2, column 1

I have a tool that can output yaml or json and when it outputs json it returns two objects concatenated, something like:

{
   'thing': 1
}
{
  'thing': 2
}

Interestingly, if I pass these directly to jq it handles them cleanly. It runs the given command on each document.

Because yq wraps jq it seems like it should be able to handle this in a like manner.

emulate -i support

jq has a feature request open to support sed-like in-place editing of files. It would be lovely if yq were to support that in advance.

e.g. yq '(.foo.bar=3)' -i foo.yaml would replace foo.yaml in-place, safely, with an implied -y. (write a temp file, close the source file, rename the temp file over the source file) [on windows, a delete or mv of the source file is also needed in there because 👎 but hey, close as we can get.

I'd be happy to put a patch up if this feature request seems reasonable.

Error when name contains a dash (-)

test.yaml contents:

test: "test output"
my-test: "my-test output"

Error when trying to access my-test:

❯ cat test.yml | yq .test
"test output"
❯ cat test.yml |yq .my-test
jq: error: test/0 is not defined at <top-level>, line 1:
.my-test
jq: 1 compile error

Unable to use yq in a makefile, no tty

Using yq in a makefile (run with GNU Make 4+) produces a fatal error. For some reason in that case sys.stdin does not have a isatty() function:

AttributeError: 'NoneType' object has no attribute 'isatty'
make[1]: *** [makefile:18: tt] Error 1
make[1]: Leaving directory '<path>'
make[1]: Entering directory '<path>'
Traceback (most recent call last):
  File "/usr/bin/yq", line 11, in <module>
    load_entry_point('yq==2.7.0', 'console_scripts', 'yq')()
  File "/usr/lib/python3.7/site-packages/yq/__init__.py", line 132, in main
    if sys.stdin.isatty() and not args.files:
AttributeError: 'NoneType' object has no attribute 'isatty'

The same command run from a shell works fine.

Create a Debian package

yq is currently distributed as a Homebrew formula (#11), and that's awesome!

As a suggestion, I think it would be great if yq was distributed as a Debian package as well. This would allow more folks to easily install it in Debian-compatible Linux distributions (like Ubuntu), doing something like:

sudo add-apt-repository ppa:kislyuk/yq
sudo apt update
sudo apt install yq -y

This would also make a real case for using yq more broadly in server scripts, Linux-based developer workstations, etc.

Can't convert sample.json with yq: yq r sample.json

Convert fails with jq: 1 compile error... Tried to convert and got the following

$ yq r sample.json
jq: error: r/0 is not defined at <top-level>, line 1:
r
jq: 1 compile error
  • Using jq 1.5_3
$ yq --version
yq 2.4.1

$ jq --version
jq-1.5

preserve/restore indentation

input.yml:

a: b
c:
  - d

Command:
yq -y '.c += ["e"]' input.yml

Output:

a: b
c:
- d
- e

Expect output:

a: b
c:
  - d
  - e

Stop pretending input == output formats

The current code makes the assumption that input and output formats are always the same.

I think it would be much more useful if the input and output stages could be separated and options mixed or matched at will. This would turn the project into a general purpose transcoder as well as a query engine for each format. It already does all the transcoding anyway, It seems like an arbitrary restriction to force transcoding back to the same format it came from.

My fix for passthrough JSON input in #57 already introduces one specific scenario of mismatched formats being useful, but a more general purpose solution where input and output formats can be set independently would add a lot more flexibility.

Don't print 'null' to stdout for no-match

For example, printing null to stdout breaks the following:

my_val="$(echo 'foo: bar' | yq -re '.someotherkey' || echo 'default_val')"

Since this will result in null instead of default_val.

Instead, yq should output an error message to stderr on no match, at least in the case of -e.

Suggestion: A self-contained binary for easier installation

Hi @kislyuk, thanks for maintaining a great project 👍

Would you mind if I contributed a script to build pex binary for yq?
I'd greatly appreciate it if you could build binaries with my script and host these as GitHub releases for easier installation.

It would also helps #11 by simplifying the installation process - you are no longer likely to need running pip install from within the brew. Instead, just install python3 and the pex binary.

For reference, I've done the same thing on physera/onelogin-aws-cli#29.

Enable configurable indentation

e.g.

foo.json

{
  "test": {
    "s1": "bar",
    "s2": [
      "snowflake",
      "s3",
      "gcloud"
    ]
  }
}

yq -y . foo.json

test:
  s1: bar
  s2:
  - snowflake
  - s3
  - gcloud

When valid yaml should be:

 test:
   s1: bar
   s2:
     - snowflake
     - s3
     - gcloud

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.