toys

Tools and things that make my life easier - y'all might like them too

View the Project on GitHub pfuntner/toys

json-shell

Purpose

An interactive shell-like tool to explore a JSON file.

I am often frustrated by large complicated JSON objects and had this wild idea of treating an object like a Unix filesystem: there is a root, child nodes, and grandchildren, you can navigate with cd along with other familiar Unix commands.

Syntax

Syntax: json-shell [-v] json-filename

Options

| Option | Description | Default | | —— | ———– | ——- | | -v | Enable verbose debugging | Debugging is not enabled |

Examples

Unlike a lot of my other tools, the examples are in the forms of interactive subcommands in the tool so I’ll give examples of those.

Since there are so many subcommands and some of the help information is a little long, I’ll provide a table of contents:

I’ll also use the following JSON file in examples:

{
  "bools": [true, false],
  "ints": [42, 32768, -1],
  "floats": [3.141592654, 2.7182818285, -0.000001],
  "strs": ["a", "b", "foo", "bar"],
  "none": null,
  "dict": {
    "1": [".", "one", "One", "ONE"],
    "2": ["..", "two", "Two", "TWO"]
  }
}

The prompt

The tool prompts for subcommands includes the current location much like the current working directory as in a filesystem.

$ json-shell sample.json
Confoozed?  Try `help`
/> 

The location is / since you always begin in the root node. The > is asking for a subcommand to be entered.

help

You can get general help of all subcommands:

/> help
Navigate around a JSON document, just like a shell, only different!

Commands:

  cat       Display the current node or a child
              `cat` by itself displays the current node
              `cat key` display child element `key` of the current node

  cd        Change the current node
              `cd` by itself goes to root node
              `cd ..` go to parent node as long as you're not already at the root
              `cd key` goes to a child node if the key exists and its node is a dictionary or list

  describe  Describe a node
              `describe` describes the current node
              `describe key` describes the child element `key` of the current node

  exit      Exit from json-shell

  help      Display help

  ls        List keys in the current node

  pwd       Print the current node - note that this is included in each prompt

  quit      Exit from json-shell
/>

or you can get help on a specific subcommand:

/> help cd
Change the current node
  `cd` by itself goes to root node
  `cd ..` go to parent node as long as you're not already at the root
  `cd key` goes to a child node if the key exists and its node is a dictionary or list
/> 

exit

The exit and quit subcommands terminate the tool and return you to the Unix shell. The subcommands are synonymous.

cd

I’m taking great liberties with the name because we’re not talking about a current working directory but it’s a similar concept. You can cd into any child of the current node that’s a list or dictionary:

/> cd bools
/bools> cd ..
/> cd dict
/dict> cd 1
/dict/1> cd
/> 

The keys you can cd into are based on the type of node you’re currently in:

You don’t have to treat the key differently based on whether you’re in a list or dicitonary. The tool knows what type of key is needed.

There are invalid cds based on the current node:

/> cd foo
'foo' is not a key
/> cd floats
/floats> cd 3
3 is out of range
/floats> cd -1
-1 is out of range
/floats> cd 0
0 is not a list or dictionary
/floats> cd foo
'foo' is not an integer: invalid literal for int() with base 10: 'foo'
/floats> 

ls

The ls subcommand displays the keys of the current node:

/> ls
bools  ints  floats  strs  none  dict
/> cd dict
/dict> ls
1  2
/dict> cd 1
/dict/1> ls
0  1  2  3
/dict/1> 

cat

cat will display the current or target node and all of its children.

/> cat
{
  "bools": [
    true,
    false
  ],
  "ints": [
    42,
    32768,
    -1
  ],
  "floats": [
    3.141592654,
    2.7182818285,
    -1e-06
  ],
  "strs": [
    "a",
    "b",
    "foo",
    "bar"
  ],
  "none": null,
  "dict": {
    "1": [
      ".",
      "one",
      "One",
      "ONE"
    ],
    "2": [
      "..",
      "two",
      "Two",
      "TWO"
    ]
  }
}
/> cd dict
/dict> cat
{
  "1": [
    ".",
    "one",
    "One",
    "ONE"
  ],
  "2": [
    "..",
    "two",
    "Two",
    "TWO"
  ]
}
/dict> cat 1
[
  ".",
  "one",
  "One",
  "ONE"
]
/dict>

describe

The describe subcommand describes the current or target node:

/> describe
/ is a dict with 6 elements
/> describe ints
/ints is a list with 3 elements
/> cd ints
/ints> describe
/ints is a list with 3 elements
/ints> describe 0
/ints/0 is a int
/ints> 

pwd

The pwd subcommand prompts the location of the current node - in a filesystem, you might think of this as the current working directory. It’s also part of each and every prompt but it’s such a popular command and it was an easy thing to add so I added it.

Notes