Git Product home page Git Product logo

jj's Introduction

JJ
JSON Stream Editor

JJ is a command line utility that provides a fast and simple way to retrieve or update values from JSON documents. It's powered by GJSON and SJSON under the hood.

It's fast because it avoids parsing irrelevant sections of json, skipping over values that do not apply, and aborts as soon as the target value has been found or updated.

Getting started

Install

Mac (Homebrew)

brew install tidwall/jj/jj

Build

make

Or download a pre-built binary for Linux, OSX, Windows, or FreeBSD.

Usage

$ jj -h

usage: jj [-v value] [-purOD] [-i infile] [-o outfile] keypath

examples: jj keypath                      read value from stdin
      or: jj -i infile keypath            read value from infile
      or: jj -v value keypath             edit value
      or: jj -v value -o outfile keypath  edit value and write to outfile

options:
      -v value             Edit JSON key path value
      -p                   Make json pretty, keypath is optional
      -u                   Make json ugly, keypath is optional
      -r                   Use raw values, otherwise types are auto-detected
      -n                   Do not output color or extra formatting
      -O                   Performance boost for value updates
      -D                   Delete the value at the specified key path
      -l                   Output array values on multiple lines
      -i infile            Use input file instead of stdin
      -o outfile           Use output file instead of stdout
      keypath              JSON key path (like "name.last")

Examples

Getting a value

JJ uses a path syntax for finding values.

Get a string:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name.last
Smith

Get a block of JSON:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name
{"first":"Tom","last":"Smith"}

Try to get a non-existent key:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name.middle
null

Get the raw string value:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -r name.last
"Smith"

Get an array value by index:

$ echo '{"friends":["Tom","Jane","Carol"]}' | jj friends.1
Jane

JSON Lines

There's support for JSON Lines using the .. path prefix. Which when specified, treats the multi-lined document as an array.

For example:

{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}
..#                   >> 4
..1                   >> {"name": "Alexa", "age": 34}
..#.name              >> ["Gilbert","Alexa","May"]
..#[name="May"].age   >> 57

Setting a value

The path syntax for setting values has a couple of tiny differences than for getting values.

The -v value option is auto-detected as a Number, Boolean, Null, or String. You can override the auto-detection and input raw JSON by including the -r option. This is useful for raw JSON blocks such as object, arrays, or premarshalled strings.

Update a value:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v Andy name.first
{"name":{"first":"Andy","last":"Smith"}}

Set a new value:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v 46 age
{"age":46,"name":{"first":"Tom","last":"Smith"}}

Set a new nested value:

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v relax task.today
{"task":{"today":"relax"},"name":{"first":"Tom","last":"Smith"}}

Replace an array value by index:

$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.1
{"friends":["Tom","Andy","Carol"]}

Append an array:

$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.-1
{"friends":["Tom","Andy","Carol","Andy"]}

Set an array value that's past the bounds:

$ echo '{"friends":["Tom","Jane","Carol"]}' | jj -v Andy friends.5
{"friends":["Tom","Andy","Carol",null,null,"Andy"]}

Set a raw block of JSON:

$ echo '{"name":"Carol"}' | jj -r -v '["Tom","Andy"]' friends
{"friends":["Tom","Andy"],"name":"Carol"}

Start new JSON document:

$ echo '' | jj -v 'Sam' name.first
{"name":{"first":"Sam"}}

Deleting a value

Delete a value:

$ echo '{"age":46,"name":{"first":"Tom","last":"Smith"}}' | jj -D age
{"name":{"first":"Tom","last":"Smith"}}

Delete an array value by index:

$ echo '{"friends":["Andy","Carol"]}' | jj -D friends.0
{"friends":["Carol"]}

Delete last item in array:

$ echo '{"friends":["Andy","Carol"]}' | jj -D friends.-1
{"friends":["Andy"]}

Optimistically update a value

The -O option can be used when the caller expects that a value at the specified keypath already exists.

Using this option can speed up an operation by as much as 6x, but slow down as much as 20% when the value does not exist.

For example:

echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -v Tim -O name.first

The -O tells jj that the name.first likely exists so try a fasttrack operation first.

Pretty printing

The -p flag will make the output json pretty.

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -p name
{
  "first": "Tom",
  "last": "Smith"
}

Also the keypath is optional when the -p flag is specified, allowing for the entire json document to be made pretty.

$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj -p
{
  "name": {
    "first": "Tom",
    "last": "Smith"
  }
}

Ugly printing

The -u flag will compress the json into the fewest characters possible by squashing newlines and spaces.

Performance

A quick comparison of jj to jq. The test json file is 180MB file of 206,560 city parcels in San Francisco.

Tested on a 2015 Macbook Pro running jq 1.5 and jj 1.0.0

Get the lot number for the parcel at index 10000

jq:

$ time cat citylots.json | jq -cM .features[10000].properties.LOT_NUM
"091"

real    0m5.486s
user    0m4.870s
sys     0m0.686s

jj:

$ time cat citylots.json | jj -r features.10000.properties.LOT_NUM
"091"

real    0m0.354s
user    0m0.161s
sys     0m0.321s

Update the lot number for the parcel at index 10000

jq:

$ time cat citylots.json | jq -cM '.features[10000].properties.LOT_NUM="12A"' > /dev/null

real    0m13.579s
user    0m16.484s
sys     0m1.310s

jj:

$ time cat citylots.json | jj -O -v 12A features.10000.properties.LOT_NUM > /dev/null

real    0m0.431s
user	0m0.201s
sys     0m0.295s

Contact

Josh Baker @tidwall

License

JJ source code is available under the MIT License.

jj's People

Contributors

dotiful avatar mmtevelde avatar stensonb avatar tidwall 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

jj's Issues

Set value to parsed JSON fragment from another file

Is it possible to extend functionality with setting value from another JSON file (parsed of course)?

I tried on Windows something like this

jj -i fragment.json -o temp.json -u
set /p fragment=<temp.json
jj -i source.json -v %fragment% Address

but it inserts a string value instead of JSON object. I believe on Linux I could use $1 to pipe argument, unfortunately, Widows pipes are very limited.

Can you delete from objects in an array?

Let's say I have JSON that includes an array, each element of which is a JSON object. Can I modify those objects?

{
  "items" : [
    { "geometry" : [0,0], "properties": { "name": "Null Island", "area": 1000 } },
    { "geometry" : [40.7128,-74.0060], "properties": { "name": "Manhattan", "area": 14604 } }
  ]
}

I can select and view items.#.properties.area, but I'd like to delete area from each item. Is that possible but I'm just doing it wrong?

What is jj's long term goal?

tl;dr: I guess if I'm asking for anything with all the following, it's clarification: is feature-parity with jq an eventual goal for jj, or is it meant to only ever serve for easier access of JSON values in Go app code?

Although tidwall/gjson#161 provided one necessary capability, this kind of task remains impossible with GJSON path syntax and jj. I have a nested structure, but I'm only interested in how many times a certain key has the same value across all objects:

# diagnostics.json
{
  "nodes": {
    "000-000-0000": {
      "node_type": "server"
    },
    "000-111-0001": {
      "node_type": "asav"
    },
    "222-000-0202": {
      "node_type": "server"
    },
  } 
}

In other words, how many times is node_type "server", "asav", or any other value which I can't know ahead of time?

With jq, this is fairly straightforward:

jq '.nodes 
  | [.[].node_type]  # Makes an array of all sub-objects' node_type values
  | group_by(.)      # Sorts the array and groups alike elements into nested arrays
  | map(             # Makes an object for each nested array like {"key: "server", "value": 2}
    { "key": (.[0]), "value": . | length }
  ) | from_entries  # Turn the arrayed objects into a single object
' diagnostics.json

# {
#    "server": 2,
#    "asav": 1
# }

With jj, I can get as far as making a list of the node_types with

nodes.@values.#.node_type

# ["server", "asav", "server"]

but there is no way to group or even sort this array for further transformation using just jj.

I understand that GJSON is a Go library and those kinds of operations are, not unreasonably, expected to be implemented in app code. However, the README presents jj as an alternative to jq, which describes itself as "sed for JSON." That's a few steps beyond what is currently possible with jj and GJSON's path syntax, so jj is only a viable alternative for a subset of problems which jq aims to address despite its clear speed advantage.

Request: Remove trailing white spaces

First, thanks for making and maintaining this. This largely matches the "pretty" format I was looking for.

One problem I've come across is trailing white spaces behind commas at the end of lines. As a solution, I've been cleaning it up with sed....which is a little hacky, but I've been unable to modify the code the way I'd like it. The reason this is a problem is because at work we have git hooks in place that flag on formatting issues - and this is one.

sed -i "" 's/[[:space:]]*$//' file.json

If you could assist, that would be appreciated.

Thanks,
James

Just wanted to say thanks

Hopefully this is encouraging. THANK you for your work on this!! My job is kind of the 'fix it' guy that tries to fill the gaps when our applications do things that were not in the original design. So that means parsing through large chunks of JSON to pull out the parts we don't need, insert the parts we do need, and push it back up via REST call. I also do a lot of programming in Go, so I came across JJ through godoc. There are things you can do with JJ that you just can't do with grep, sed, awk etc. and it's become one of those tools that I wind up putting on all our servers. I like that it's written in Go. Its one binary with 0 dependancies, I don't have to worry about installing 35 other items to get it to work. ๐Ÿ‘

The only enhancement I'd like to see is the ability to search. Who knows I might write it. :) There are times I know what I am looking for is in a certain area, or in an array. Like "services.system.circuit.#" <-- The unique circuit number is in that array somewhere. In bash I can loop for it, but it would be cool if JJ could search for it.

Thanks again.

Root object

Using this file:

$ cat z.json
{"name":{"first":"Tom","last":"Smith"}}

JQ can get the root object, AKA the whole file:

$ jq . z.json
{
  "name": {
    "first": "Tom",
    "last": "Smith"
  }
}

JSONed can get a block, but seems to have no way to get the whole file:

$ jsoned -i z.json name
{"first":"Tom","last":"Smith"}

Granted, this might only be useful when combined with pretty printing, otherwise
output is identical to cat.

Small script to test all examples at once

#!/usr/bin/env bash

print_examples() {
  json_example() {
    cat <<END
{
  "menu": {
    "id": "file",
    "value": "File",
    "popup": {
      "menuitem": [
        {
          "value": "New",
          "onclick": "CreateNewDoc()"
        },
        {
          "value": "Open",
          "onclick": "OpenDoc()"
        },
        {
          "value": "Close",
          "onclick": "CloseDoc()"
        }
      ]
    }
  }
}
END
  }

  :

  declare select_example="${select_example:+}"

  declare -a iarr_jj_examples=(
    "getting_a_value"
    "get_a_block_of_json"
    "try_to_get_a_non__existent_key"
    "get_the_raw_string_value"
    "get_an_array_value_by_index"
    "json_lines_1"
    "json_lines_2"
    "json_lines_3"
    "json_lines_4"
    "update_a_value"
    "set_a_new_value"
    "set_a_new_nested_value"
    "replace_an_array_value_by_index"
    "append_an_array"
    "set_a_raw_block_of_json"
    "start_new_json_document"
    "delete_a_value"
    "delete_an_array_value_by_index"
    "delete_last_item_in_array"
    "optimistically_update_a_value"
    "pretty_printing"
    "ugly_printing"
  )

  declare -A aarr_jj_examples=(
    [getting_a_value]="json_example | jj menu.id"
    [get_a_block_of_json]="json_example | jj menu.popup.menuitem"
    [try_to_get_a_non__existent_key]="json_example | jj menu.popuppet"
    [get_the_raw_string_value]="json_example | jj -r menu.popup"
    [get_an_array_value_by_index]="json_example | jj menu.popup.menuitem.2"
    [json_lines_1]="json_example | jj ..#"
    [json_lines_2]="json_example | jj ..0"
    [json_lines_3]="json_example | jj ..#.value"
    [json_lines_4]="json_example | jj menu.popup.menuitem..#[value=Open]"
    [update_a_value]="json_example | jj -v Test menu.popup.menuitem"
    [set_a_new_value]="json_example | jj -v Value_Test Key_Test"
    [set_a_new_nested_value]="json_example | jj -v Value_Test Key_Test.test_nested"
    [replace_an_array_value_by_index]="json_example | jj -v Value_Test menu.popup.menuitem.1"
    [append_an_array]="json_example | jj -v Value_Test menu.popup.menuitem.-1"
    [set_a_raw_block_of_json]="json_example | jj -r -v ['Tom','Andy'] menu.popup.menuitem.0"
    [start_new_json_document]="printf '' | jj -v 'Sam' name.first"
    [delete_a_value]="json_example | jj -D menu.popup"
    [delete_an_array_value_by_index]="json_example | jj -D menu.popup.menuitem.0"
    [delete_last_item_in_array]="json_example | jj -D menu.popup.menuitem.-1"
    [optimistically_update_a_value]="json_example | jj -v Tim -O menu.popup.menuitem.-1"
    [pretty_printing]="json_example | jj -p menu.popup.menuitem"
    [ugly_printing]="json_example | jj -u menu.popup.menuitem"
  )

  :

  json_example | bat -P --language json

  for select_example in "${iarr_jj_examples[@]}"; do
    : "${select_example//_/ }"
    printf "\e[1;93m%s\e[0m\n\n" "${_^}"
    printf "\e[91m\$_ %s\e[0m\n\n" "${aarr_jj_examples["${select_example}"]}"

    time eval "${aarr_jj_examples["${select_example}"]}"

    printf "\n\n"
  done
}

print_examples

X86-version possible?

Hi tidwall,
thanks a lot for this very useful utility.
We use it with installers to setup default values for apps with JSON settings files.
Unfortunately, we need to support x86 applications for a few more years.

Would it be possible for you, to compile a x86-version for Windows?

Many thanks,
BR, Nick

Editing large JSON takes a lot of memory via sjson in JJ

I was trying to edit (ie add or change a field of json) with jj. I see the memory is shooting up atleast 10 times before it can process the change. So I need for editing a 1GB json atleast 11GB memory allocated. Though the whole process is fast (for a i3, 15GB RAM machine, takes ~18 secs to edit the last index), it crashes many times because of out of memory.

I have seen reference about jj caching large amounts of memory. Please let me know if this can be optimized.

FYI, Fetching data is fast and fine and only takes the same amount of memory as the size of the json for a short period while doing the GETs.

-------------------Reference issue mentioned----------

Hi pkoppstein, I'm looking into these issues. I'm believe jj is buffering too much data prior to processing and low memory systems suffer when dealing with large json files. I'll look asap and keep you posted. Thanks!

Originally posted by @tidwall in #9 (comment)

Doesn't work on huge or improperly formatted json files

I've been having a lot of specific problems that your tool would be PERFECT for, but I might be running against some bugs that are unique to my problem.

So normally I'd use jj to take a file that might not be perfect JSON (meaning that it may contain trailing slashes) and use jj to read this json file and parse it out, and then print it in the proper format in order for something else to consume that. I'm finding that this isn't working with larger json files and jj is blowing up their size (taking files from 44MB -> 5GB)

To be more specific, here's what I"m doing.

$ echo '[{"id": 1, "name": "Arthur", "age": "21"},{"id": 2, "name": "Richard", "age": "32"}]' | jj -p
# works fine
$ echo '[{"id": 1, "name": "Arthur", "age": "21"},{"id": 2, "name": "Richard", "age": "32"}]' | jq --color-output
# works fine

This works perfectly fine. I input a correct json object and both jq and jj are able to handle that.

JJ is better for me because I have what I'll call lossy JSON. My lossy json has things like trailing commas in the file that cause it to fail typical validation.

echo '[{"id": 1, "name": "Arthur", "age": "21", },{"id": 2, "name": "Richard", "age": "32",}]' | jj -p
# works fine

echo '[{"id": 1, "name": "Arthur", "age": "21", },{"id": 2, "name": "Richard", "age": "32",}]' | jq --color-output
#jq errors on me 
parse error: Expected another key-value pair at line 1, column 43

I need to read these JSON files in other programs after parsing them and making sure that they don't have these commas.
So I've been passing them through JJ and then sending them to jq to validate them.

$ echo '[{"id": 1, "name": "Arthur", "age": "21", },{"id": 2, "name": "Richard", "age": "32",}]' | jj -p  | jq --color-output 

Now I've noticed that it's only when i use jj -p that JJ does this convenient functionality that I'm leveraging to clear the trailing commas.

I want the file to be small but I also want it to be valid.
So I'm now doing something like this:

$ echo '[{"id": 1, "name": "Arthur", "age": "21", },{"id": 2, "name": "Richard", "age": "32",}]' | jj -p  | jj -u | jq --color-output 

Now I'm getting the best of both worlds. It's expensive, but I don't care since I'm more interested in making sure the data is formatted correctly and don't care about my cpu grinding this out for a few more minutes.

The problem is that passing larger files through JJ -p is not blowing up their file size like crazy. (43 -> 732M)

Here's a screenshot of what I'm seeing that I think is causing these huge size increases.

screen shot 2018-02-27 at 9 42 19 pm

Size of course, is no issue if the data is usable, however it doesn't seem to be so.

When attempting to parse the output file from just jj -p I get unusual problems.

>>> import json
>>> data = json.load(open('alabama_2012_expanded.json'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/json/__init__.py", line 290, in load
    **kw)
  File "/usr/lib64/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
RuntimeError: maximum recursion depth exceeded while calling a Python object

I've even tried expanding the python recursion depth to 10,000 and it still doesn't work.

I've tried going from jj -p | jj -u and then passing that to jq to validate it. But when I validate it I get problems like this.

$ cat lossy_alabama_2012.json | jj -p | jj -u  > alabama_2012_cleaned.json
$ cat alabama_2012_cleaned.json | jq --color-output
parse error: Unfinished JSON term at EOF at line 1, column 42370384

Here's an example of one of these huge JSON files I'm working with it's 43M

TL; DR : jj -p is blowing up filesizes, and passing jj -p | jj -u is making files that aren't valid.

My question for you, do you have any idea what could be going on here? I can't seem to get a proper version of this file saved the way I need it to be.

Support colored output on -p

It would be nice to have different colors for keys and values when printing with the -p flag. Do you plan to do it?

Key duplication bug when setting values with -v flag on dot-escaped JSON paths

What version I'm using:

Hi, I'm testing this with jj-1.2.1 on Linux.

Bug description:

I have noticed some strange behaviour where using -v to set a value will result in double output for the same key when using backslashes to escape periods in a JSON "path".

Repro steps:

Consider a little sample.json file with the content below:

{
  "plain_example": "tomato", 
  "dotted.example1": "carrot", 
  "dotted.example2": "eggplant"
}

So far so good. I run jj on it to print it as-is and it prints as expected:

> jj -i sample.json -p
{
  "plain_example": "tomato", 
  "dotted.example1": "carrot", 
  "dotted.example2": "eggplant"
}

First let's validate that the -v flag for editing a document does in fact work. Let's try with the plain_example key...

> jj -i sample.json -v potato "plain_example" -p
{
  "plain_example": "potato", 
  "dotted.example1": "carrot", 
  "dotted.example2": "eggplant"
}

So far so good! plain_example which was "tomato" is now "potato". ๐Ÿ‘


Now, let's say I want to edit the key dotted.example1 to the same value. At first, I forget to escape the periods -- which is my bad and not a bug -- and it gives me this output:

> jj -i ./_vscode_rez_config/settings.json -v potato "dotted.example1" -p
{
  "dotted": {
    "example1": "potato"
  }, 
  "plain_example": "tomato", 
  "dotted.example1": "carrot", 
  "dotted.example2": "eggplant"
}

Then I read the README a bit closer and learn that I need to escape them... Ok! No problem, I tell myself... let's try:

> jj -i ./_vscode_rez_config/settings.json -v potato "dotted\.example1" -p
{
  "dotted.example1": "potato", 
  "plain_example": "tomato", 
  "dotted.example1": "carrot", 
  "dotted.example2": "eggplant"
}

Woah, what the..?! Escaping worked as I don't get nesting in the result anymore, but now dotted.example1 exists twice! That's not legal JSON. ๐Ÿ’ฉ

Could it be the printing code?? Let's rule it out by writing a file out directly with the -o flag:

> jj -i ./_vscode_rez_config/settings.json -v potato "dotted\.example1" -o /tmp/output.json
> cat /tmp/output.json
{"dotted.example1":"potato",
    "plain_example": "tomato",
    "dotted.example1": "carrot",
    "dotted.example2": "eggplant"
}

Same issue, key appears twice and curiously the output is not identical as with -p, plus it's not formatted as prettily as one would expect! Something is definitely wrong here. ๐Ÿ˜ฎ

Hope you can find the bug. I really love the tool otherwise! :)

Pretty print

Using this file:

$ cat x.json
{"name":{"first":"Tom","last":"Smith"}}

JQ can pretty print a block:

$ jq .name x.json
{
  "first": "Tom",
  "last": "Smith"
}

JSONed seems to have no way to do that:

$ jsoned -i x.json name
{"first":"Tom","last":"Smith"}

README.md - timings and maxrss

On the README.md page, some comparisons with jq are made.
Since jq also has a streaming parser, I believe it would be
helpful to compare the performance of the two streaming parsers.

It would also be helpful to add something about memory utilization;
since my /usr/bin/time gives maxrss, I've given that below.

Here are the results of my timings on a 3GHz 16MB RAM machine:

(i) jj 'features.10000.properties.LOT_NUM' -i citylots.json

091
user   0.01s
sys    0.14s 
maxrss 197627904

(ii) jq-1.5 -n --stream 'first(inputs | select(.[0] == ["features",10000,"properties","LOT_NUM"])) | .[1]' citylots.json

"091"
user   0.60
sys    0.00
maxrss 2084864 

(iii) As above but with jq-1.6rc1

"091"
user   0.61
sys    0.00
maxrss 2072576

optimizing jj -l @this

I've successfully used jj to "splat" a very large top-level by running:

jj -l @this

This is very fast but consumes a large amount of memory: for my 1GB file, it requires 5GB RAM, even though each top-level array item is very small.

I was wondering whether there is another way to "splat" a top-level array that would (ignoring overhead) essentially require only as much memory as the largest item in the array, while still being reasonably fast.

If not, could the presence of the -l flag be taken into account when optimizing the use of memory?

[suggestion] print array value

example_json:[{"token":"147","symbol":"abcd"},{"token":"92","symbol":"efgh"},{"token":"118","symbol":"ijkl"}]

jj -l [0] it print first/one array value`

$ cat tmp | ../jj -l [0]
{"token":"147","symbol":"abcd"}

jj -l [0,1,2] it print first 3 array value

$ cat tmp | ../jj -l [0,1,2]
{"token":"147","symbol":"abcd"}
{"token":"92","symbol":"efgh"}
{"token":"118","symbol":"ijkl"}

So my suggestion is can we print sequence of array value?
like if i want to print value of array 5 to array 25 so what to do?
can we do like that jj -l [5-25] or something else

jj -p ..

There's support for JSON Lines using the .. path prefix. Which when specified, treats the multi-lined document as an array.

This doesnโ€™t seem to work in the way one would hope with the -p option:

$ jj -p ..
1
2
$

[enhancement] traverse directory to produce json

Suppose i have

./thing_one/params.json
./thing_one/results.json
./thing_two/params.json
./thing_two/results.json

Could we make something like jj -p -r . hat traverses ./ to fetch all the json, and display them as a big json with proper formatting and indentation? So it would produce something like:
{
"thing_one": {
"params: { },
"results": { }
},
"thing_two": {
........
}
}

BTW, awesome utility. Absolutely love it. It's been making my life so much easier.

Multiple changes to the same file in one run

Hey there,

Thank you for an awesome tool! For my use case I need to do multiple small modifications to the same json document and I'd like to do them in one call to the binary.

So for example, instead of:

jj-v1.2.1 -v 500 -O -i my_file.json -o my_file.json bytes_received
jj-v1.2.1 -v 1500 -O -i my_file.json -o my_file.json bytes_expected
jj-v1.2.1 -v 75.62 -O -i my_file.json -o my_file.json upload_duration

I'd like to do something like this:

jj-v1.2.1 -v 500,1500,75.62 -O -i my_file.json -o my_file.json bytes_received,bytes_expected,upload_duration

Reasoning is, less child processes (which are costly in node.js, which I am using) and reading in the same json file only once in Go instead of multiple times (https://github.com/tidwall/jj/blob/master/cmd/jj/main.go#L151) and also saving it only once to disk instead of multiple times (https://github.com/tidwall/jj/blob/master/cmd/jj/main.go#L246).

Is this something that you'd consider implementing, or maybe even accepting a PR for it? ๐Ÿ˜ฑ

Setting values in JSON lines

Hello!

I find this API more readable than jq. However, I'm not sure how to perform some actions:

JSON lines example:

{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}

How would I update all names to "Peter"?
How would I update "name" key to "firstname"?

Thanks!

(I tried jj -v Peter '..#.name')

ENH: Support newline delimited json (aka json lines or ndjson)

jj is cool, the syntax is much simpler than jq and it can also deal with much deeper recursion (jq can only handle nodes 512 deep) whereas jj seems to be fine up to much higher depths.

It should be quite easy to extend jj to work with ndjson input - unfortunately this doesn't seem to be supported yet.

In the field I work in (bioinfo) ndjson is very common, would be great if you could have a look at this.

Primarily reading from ndjson should be supported, setting might be a side effect.

should create an array when keypath is key.-1

first, i create a blank json file by running touch arraytest.json
then command jsoned -v 1 array1.0 -i arraytest.json -o arraytest.json will results in :

{"array1":[1]}

this is expected, but command jsoned -v 1 array2.-1 -i arraytest.json -o arraytest.json will results in :

{"array2":{"-1":1}}

this time jsoned treats -1 in keypath array2.-1 as normal key instead of an array index

I expect jsoned treats -1 in keypath array2.-1 as an array index , automatically create an array if the array is absent, or appends the value after the last element if the array exists

@tidwall

root array not working properly (# and -1)

Consider the following json ["first","last"], we can access elements by positive index

> echo '["first","last"]' | jj 1
last

but we can't obtain the number of elements

> echo '["first","last"]' | jj # 
jj - JSON Stream Editor 1.2.3
missing required option: "keypath"
...

we can't access the last element (negative index)

> echo '["first","last"]' | jj -1 
jj - JSON Stream Editor 1.2.3
unknown option argument: "-1"
...

and we can't query with #[...] or #[...]#.

CRLF

shouldnt JJ produce CRLF on Windows?

doesnt bother me either way but Windows uses this for line endings, not LF by itself

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.