简体   繁体   中英

How to get root keys and key types using jq

Let's take this simple data file: http://data.cdc.gov/data.json

I know how to get the root key names:

jq keys_unsorted[] -r data.json

which produces:

@context
@id
@type
conformsTo
describedBy
dataset

And I know how to get the key types:

jq 'map(type)' data.json

Which produces:

[
  "string",
  "string",
  "string",
  "string",
  "string",
  "array"
]

Is there not some way of combining this in returning pairs? (what I am really trying to do is find the key name of the first root level array, if any). I can write a routine to figure it out, but this seem inelegant.

Bonus side question: How to you determine the type of a key (eg, I would send "dataset" to jq in some form and would get "array" in return)?

The simplest approach to writing queries that depend on both key names and values is to use one of the "*_entries" family of filters. In your case:

$ jq -c 'to_entries[] | [.key, (.value|type)]' data.json

["@context","string"]
["@id","string"]
["@type","string"]
["conformsTo","string"]
["describedBy","string"]
["dataset","array"]    

If you wanted this presented in a more human-readable fashion, consider using @csv or @tsv, eg

$ jq -r 'to_entries[] | [.key, (.value|type)] | @csv' data.json
"@context","string"
"@id","string"
"@type","string"
"conformsTo","string"
"describedBy","string"
"dataset","array"

Or with less noise:

$ jq -r 'to_entries[] | "\(.key) \(.value|type)"' data.json
@context string
@id string
@type string
conformsTo string
describedBy string
dataset array

Bonus question

Here's a parametric approach to the second question. Let the file query.jq contain:

.[$key]|type

Then:

$ jq -r --arg key dataset -f query.jq data.json
array
jq 'first(path(.[] | select(type == "array"))[0])' < data.json

The top-level items .[] are filtered out with select(type == "array") which selects only items of array type; path() returns array representation of the path in . , ie the key names of the array items; first() extracts the first path.

So the result of the command is key name of the first top-level array item.

Sample Output

"dataset"

How to you determine the type of a key (eg, I would send "dataset" to jq in some form and would get "array" in return).

You probably mean "the type of a value", because the keys must be strings in JSON. If the path is known (eg .dataset ), then the type of the object can be fetched with the type function:

jq '.dataset | type' < data.json

Sample Output

"array"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM