Skip to content

Using jc With Different Shells

Bruce Weirdan edited this page Jun 22, 2024 · 58 revisions

jc can be used with most any shell, but some more modern shells have built-in JSON deserialization support. Along with built-in object filtering capabilities this makes it very easy to assign a specific JSON value to a variable without the need to use tools like jq, jello, jp, etc.

This article goes over some simple examples of how jc can be used in modern and traditional shells.

Bash

You will typically use JSON filter utilities like jq, jello, jp, etc. to work with JSON output in Bash.

$ myvar=$(dig www.google.com | jc --dig | jq -r '.[0].answer[0].data')
$ echo $myvar
64.233.185.104

$ myvar=$(jc dig www.google.com | jello -r '_[0].answer[0].data')
$ echo $myvar
64.233.185.104

$ myvar=$(jc dig www.google.com | jp -u '[0].answer[0].data')
$ echo $myvar
64.233.185.104

For more information and examples on using JSON in Bash, see Practical JSON at the Command Line and Practical JSON at the Command Line (using Jello)

Elvish

You can use the from-json builtin to read JSON data into a variable

~> var myvar = (dig www.google.com | jc --dig | from-json)
~> put $myvar[0]['answer'][0]['data']
▶ 64.233.185.104

See https://elv.sh/ref/builtin.html#from-json for more info.

Fish

You will typically use JSON filter utilities like jq, jello, jp, etc. to work with JSON output in Fish.

$ set myvar (dig www.google.com | jc --dig | jq -r '.[0].answer[0].data')
$ echo $myvar
64.233.185.104

$ set myvar (jc dig www.google.com | jello -r '_[0].answer[0].data')
$ echo $myvar
64.233.185.104

$ set myvar (jc dig www.google.com | jp -u '[0].answer[0].data')
$ echo $myvar
64.233.185.104

See https://fishshell.com/docs/current/index.html for more info.

Murex

Murex includes a cast json command to convert a string to a JSON data structure. You can also set the object type directly when setting the variable. (e.g. set json myvar). Then you can use either Index or Element notation to access nested values within the JSON variable.

~ » jc dig www.google.com -> set json myvar
~ » $myvar[[.0.answer.0.data]] -> set mydata
~ » out $mydata
64.233.185.104

See https://murex.rocks/ for more info.

NGS

In Next Generation Shell, you will typically use the double-backtick "run and parse" syntax with jc and built-in features for data filtering and other manipulation.

myvar = ``jc dig www.google.com``[0].answer[0].data
echo(myvar)

Returns:

64.233.185.104

Filter Examples:

``jc ifconfig``.the_one({"name": "en0"}).ipv4_addr
``jc ifconfig``.name.filter(/tun/)
``jc ifconfig``.filter({"name": /tun/}).mtu

Notes:

  • Non-zero exit code from jc will cause an exception to be thrown.
  • The double-backtick will parse any JSON, not just output of jc.
  • the_one() will throw an exception if there is not exactly one matching item.
  • .name and .mtu result an array as .FIELD_NAME on an array is defined as mapping each element to the given field.

Next Generation Shell documentation: https://ngs-lang.org/doc/latest/index.html

Nushell

You can use the from json builtin to read JSON data into a variable

> let myvar = (dig www.google.com | jc --dig | from json)
> echo $myvar | get 0.answer.0.data
64.233.185.104

You can also use a third-party module to make the conversion automatic:

: jc ping -4 -c 2 google.com
╭──────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────╮
 destination_ip        216.58.209.46                                                                            
 data_bytes            56                                                                                       
 pattern                                                                                                        
 destination           google.com                                                                               
 duplicates            0                                                                                        
 packets_transmitted   2                                                                                        
 packets_received      2                                                                                        
 packet_loss_percent   0.00                                                                                     
 time_ms               1001.00                                                                                  
 round_trip_ms_min     3.87                                                                                     
 round_trip_ms_avg     4.04                                                                                     
 round_trip_ms_max     4.21                                                                                     
 round_trip_ms_stddev  0.17                                                                                     
                       ╭───┬───────┬───────────┬───────┬───────────────┬──────────┬─────┬─────────┬───────────╮ 
 responses              # │ type  │ timestamp │ bytes │  response_ip  │ icmp_seq │ ttl │ time_ms │ duplicate │ │
                       ├───┼───────┼───────────┼───────┼───────────────┼──────────┼─────┼─────────┼───────────┤ 
                        0  reply                64  216.58.209.46         1  120     4.21  false      
                        1  reply                64  216.58.209.46         2  120     3.87  false      
                       ╰───┴───────┴───────────┴───────┴───────────────┴──────────┴─────┴─────────┴───────────╯ 
╰──────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────╯
: (jc ping -4 -c 2 google.com).round_trip_ms_avg
6.054

See https://www.nushell.sh/book/ for more info.

Oil

You can use the json read builtin to read JSON data into a variable

$ dig www.google.com | jc --dig | json read myvar
$ var mydata = myvar[0]['answer'][0]['data']
$ echo $mydata
64.233.185.104

See https://www.oilshell.org/release/latest/doc/json.html for more info.

PowerShell

You can use the ConvertFrom-Json utility to parse JSON output from jc

PS C:\> $myvar = dig www.google.com | jc --dig | ConvertFrom-Json
PS C:\> Write-Output $myvar[0].answer[0].data
64.233.185.104

See https://techgenix.com/json-with-powershell/ for more info.

Windows Command Prompt (cmd.exe)

You can use jq, jello, jp, and other JSON filter utilities on the legacy command line and in batch files

C:\> dig www.google.com | jc --dig | jq -r .[0].answer[0].data
64.233.185.104

C:\> jc dig www.google.com | jello -r _[0].answer[0].data
64.233.185.104

C:\> jc dig www.google.com | jp -u [0].answer[0].data
64.233.185.104

To assign the value to a variable you can use the FOR /F command.

At The Command Line

C:\> FOR /F "tokens=* USEBACKQ" %i IN (`dig www.google.com ^| jc --dig ^| jq -r .[0].answer[0].data`) DO SET myvar=%i
C:\> ECHO %myvar%
64.233.185.104

In A Batch File

FOR /F "tokens=* USEBACKQ" %%i IN (`dig www.google.com ^| jc --dig ^| jq -r .[0].answer[0].data`) DO SET myvar=%%i
ECHO %myvar%

Returns:

64.233.185.104

See https://stackoverflow.com/questions/6359820/how-to-set-commands-output-as-a-variable-in-a-batch-file for more info.