Read
This command outputs a single value (e.g. a string) or a group value (e.g. a dictionary) for a given path.
The examples on this page will refer to this JSON file that can be found in the playground (you might want to copy/paste or to download it somewhere to keep it in sight).
Note that any of the four People files could be used. Thus the examples are not always using a Json explorer.
{
"Tom" : {
"age" : 68,
"hobbies" : [
"cooking",
"guitar"
],
"height" : 175
},
"Robert" : {
"age" : 23,
"hobbies" : [
"video games",
"party",
"tennis"
],
"running_records" : [
[
10,
12, 9,
10
],
[ 9,
12,
11
]
],
"height" : 181
},
"Suzanne" : {
"job" : "actress",
"movies" : [
{
"title" : "Tomorrow is so far",
"awards" : "Best speech for a silent movie"
},
{
"title" : "Yesterday will never go",
"awards" : "Best title"
},
{
"title" : "What about today?"
}
]
}
}
Simple example
Read Tom's height.
Use the option -i|--input
to specify a file as input. Otherwise Scout can read the input stream.
scout read -i People.json -f json "Tom.height"
In the next examples, the option
-i People.json -f json
will be implicitly specified.
Get a group value
Read Tom's dictionary
scout read "Tom"
will output
{
"age" : 68,
"hobbies" : [
"cooking",
"guitar"
],
"height" : 175
}
Common
Invalid paths
If the path is invalid, the command will return/throw an error with a proper message. A path can be invalid for several reasons. For instance:
- A given key does not exist in a dictionary
- An index is greater than an array element's count
- A special element is not used properly
This command will return an error because the key "score" does not exist in Tom's dictionary.
scout read "Tom.score"
When that's possible, the program will display a message to offer another possible key name. For instance the command
scout read "Tom.heiht"
will return an error but will also inform that the key 'height' is near the 'heiht' word.
Array subscripting
It's possible to access an element in an array by specifying its index.
When the index is negative, this targets an element starting from the end of the array.
This figure gives an example with the 'ducks' array.
["Riri", "Fifi", "Loulou", "Donald", "Daisy"]
[ 0 , 1 , 2 , 3 , 4 ] (Positive)
[ -5 , -4 , -3 , -2 , -1 ] (Negative)
ducks[1]
targets "Fifi"ducks[-2]
targets "Donald"
Targets Robert's second hobby.
scout read "Robert.hobbies[1]"
Targets Robert's last hobby.
scout read "Robert.hobbies[-1]"
Read command specificities
Count
It's possible to get an dictionary or an array count with the count[#]
symbol.
Get Robert hobbies count.
scout read "Robert.hobbies[#]"
Get people count.
scout read "[#]"
Keys symbol
List the keys of a dictionary with the keys list{#}
symbol.
Get the keys of the Suzanne's dictionary.
scout read "Suzanne{#}"
Output
[
"job",
"movies"
]
Array slicing
It's possible to target a slice of an array from a lower bound to an upper bound. The upper bound is included.
When a array is sliced, it's possible to continue the path with a next element that elements in the slice have in common.
A slice is specified with square brackets and a double point ':' between the bounds: '[lower:upper]'. No lower means 0 like [:10]
and no upper means the last index like [10:]
.
Use a negative index to target the last nth elements like [-4:] to target the last 4 elements or [-4: -2] to target from the last fourth to the last second element. Get Robert's first two hobbies
scout read "Robert.hobbies[:1]"
Output:
[
"video games",
"party"
]
Get Suzanne's movies titles.
scout read "Suzanne.movies[:].title"
Output:
[
"Tomorrow is so far",
"Yesterday will never go",
"What about today?"
]
Keys filtering
It's possible to target specific keys in a dictionary with a regular expression.When a dictionary is filtered, it's possible to continue the path with a next element that elements in the slice have in common.
If the provided regular expression is invalid, an error will be thrown/returned.
This element is enclosed by sharp '#' signs. For instance #.*device.*#
to target all the keys in a dictionary containing the word device.
Get Tom keys that start with 'h'.
scout read "Tom.#h.*#"
Output:
{
"hobbies" : [
"cooking",
"guitar"
],
"height" : 175
}
Get Tom and Robert first hobby.
scout read "#Tom|Robert#.hobbies[0]"
Output:
{
"Robert_hobbies_index(0)" : "video games",
"Tom_hobbies_index(0)" : "cooking"
}
Mixing
It's possible to mix the array slicing and dictionary filtering features.Get Tom and Robert first two hobbies.
scout read "#Tom|Robert#.hobbies[:1]"
Output:
{
"Tom" : [
"cooking",
"guitar"
],
"Robert" : [
"video games",
"party"
]
}
Zsh arrays
Scout allows to read a Zsh array directly from an array or dictionary.
To get a 1-dimension array from the data, the option —export|-e
can be used with the array option and by enclosing the result with brackets.
hobbies=("${(@f)$(scout read -i People.json -f json "Robert.hobbies" -e array)}")
echo $hobbies[1] # video games
The same goes for dictionaries to associative arrays with the
dictionary
option.
declare -A movie=("${(@f)$(scout read -i People.json -f json "Suzanne.movies[0]" -e dictionary)}")
echo $movie[title] # Tomorrow is so far
XML attributes
When working with XML and the read features, Scout will allow to read an attribute with a key element from 4.0.0
.
For instance with the following XML.
<Tom score="20">
<height>175</height>
<age>68</age>
</Tom>
It’s possible to read the score value.
scout read -i File.json -f json "Tom.score"
<Tom score="20">
<height>175</height>
<age>68</age>
</Tom>
The following will output 20
scout read -i File.json -f json "Tom.score"
When the following will output 68.
scout read -i File.json -f json "Tom.[1]"