Reputation: 5731
I have this Json
{
"users": [
{
"first": "Stevie",
"last": "Wonder"
},
{
"first": "Michael",
"last": "Jackson"
}
]
}
Using jq I'd like to display first and last name serially. Like so -
Stevie Wonder
Michael Jackson
This is how far I have gotten -
jq '.users[].first, .users[].last'
But it displays
"Stevie"
"Michael"
"Wonder"
"Jackson"
Notice the following:
Upvotes: 530
Views: 517049
Reputation: 12728
A little bit more steps but I noticed no one here mentions join()
. join()
only works for array so you need to construct one. To eliminate double quotes, use -r
:
echo $JSON | jq -r '.users[] | [.first,.last] | join(" ")'
,
means applying filter to the previous step's output with such order, so you .first
then you get .last
and create an array.
A small test does not show any performance degrading.
Upvotes: 1
Reputation: 17942
I recommend using String Interpolation:
jq '.users[] | "\(.first) \(.last)"'
We are piping down the result of .users[]
to generate the string ".first .last" using string interpolation. \(foo)
syntax is used for string interpolation in jq
. So, for the above example, it becomes "Stevie Wonder" (".users[].first .users[].second"
working elementwise) and "Michael Jackson".
jq reference: String interpolation
Upvotes: 734
Reputation: 4675
In addition to what others have suggested, I think that two options are worth mentioning.
$ cat file.json | jq -r '.users[] | [.first, .last] | @tsv'
Stevie Wonder
Michael Jackson
cat file.json | jq -r '.users[] | [.first, .last] | @csv'
"Stevie","Wonder"
"Michael","Jackson"
The first expression, .users[]
, unnests the objects from the outer-most array as in the code given in the question. The next expression, [.first, .last]
, creates a new array of the values for each input object, and the final expression uses the built-in functions @tsv
and @csv
to print all input arrays as tab-separated and comma-seperated values, respectively.
Similarly, it is possible to construct JSON values again, which is interesting if you just want to keep a subset of the fields:
$ cat file.json | jq -c '.users[] | {first}'
{"first":"Stevie"}
{"first":"Michael"}
Upvotes: 86
Reputation: 47833
You can use addition to concatenate strings.
Strings are added by being joined into a larger string.
jq '.users[] | .first + " " + .last'
The above works when both first
and last
are string. If you are extracting different datatypes(number and string), then we need to convert to equivalent types. Referring to solution on this question. For example.
jq '.users[] | .first + " " + (.number|tostring)'
Upvotes: 388
Reputation: 1936
my approach will be (your json example is not well formed.. guess thats only a sample)
jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")' front.json > output.txt
returns something like this
"new.domain.com-80|8.8.8.8|192.168.2.2:80|192.168.3.29:80 192.168.3.30:80"
"new.domain.com -443|8.8.8.8|192.168.2.2:443|192.168.3.29:443 192.168.3.30:443"
and grep the output with regular expression.
Upvotes: 21
Reputation: 309
This will produce an array of names
> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json
[
"Stevie Wonder",
"Michael Jackson"
]
Upvotes: 18
Reputation: 18079
I got pretty close to what I wanted by doing something like this
cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | " - " + .sub_key)' | tr -d '"'
The output of which is close enough to yaml for me to usually import it into other tools without much problem. (I am still looking for a way to basicallt export a subset of the input json)
Upvotes: 6
Reputation: 1029
While both of the above answers work well if key,value are strings, I had a situation to append a string and integer (jq errors using the above expressions)
Requirement: To construct a url out below json
pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 251 100 251 0 0 155k 0 --:--:-- --:--:-- --:--:-- 245k
{
"Node": "myconsul",
"Address": "192.168.99.103",
"ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
"ServiceName": "apache-443",
"ServiceTags": [],
"ServiceAddress": "",
"ServicePort": 1443,
"ServiceEnableTagOverride": false,
"CreateIndex": 45,
"ModifyIndex": 45
}
Solution:
curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'
Upvotes: 17