たとえば、次のユーザー名辞書があります。
"userinfo": { "alice": { "key1": 1, "key2": 2}, "bob": { "key1": 11, "key2": 22}, ... }
ユーザー名といくつかの値を含むテーブルテキストを表示したいです。
alice 1 2
bob 11 22
ユーザー名を最初の列に入れるか、値を後の列にインポートするのは簡単ですが、同じコマンドからユーザー名とその下の値を取得する.info[]|[.key1,.key2]
方法はわかりません。何度も実行して出力を貼り付けるなどjq
愚かなことをしないように努力しています。jq
答え1
これを行うには、次のコマンドを使用できます。
jq -r '.userinfo | to_entries[] | [.key, .value.key1, .value.key2] | @tsv'
最初にデータをentries
参照できるように変換し、次に目的の値にを生成し、最後に演算子を使用して出力list
に変換します。別の形式にしたい場合は、詳細をお読みください。tab-seperated-values
@tsv
ここ。
また、対応するフラグを使用して生出力を取得します。それ以外の場合は、その文字を-r
取得します。 :)"\t"
@さんのコメント0 石 0:不明な数のキー*がある場合は、[ .key, .value[] ]
以下を使用してすべて取得できます。
答え2
$ jq -r '.userinfo | keys[] as $k | [ $k, .[$k][] ] | @tsv' file
alice 1 2
bob 11 22
file
ここでは、入力が有効なJSON文書であると仮定します。たとえば、次のようになります。
{
"userinfo": {
"alice": {
"key1": 1,
"key2": 2
},
"bob": {
"key1": 11,
"key2": 22
}
}
}
この式は最上位オブジェクトをjq
選択し、そのオブジェクトのキーを繰り返し、各キーは内部変数に割り当てられます。特に、すべてのキー(ユーザー名)に対して繰り返しが発生します。userinfo
$k
[]
keys[]
各反復ごとに配列が構成されます[ $k, .[$k][] ]
。つまり、キー自体で構成された配列とその特定のキーに関連するオブジェクトの値が続きますuserinfo
(下のキーが何で.[$k]
あるか、キーが何個あるかに関係なく無視します。キーkey1
とkey2
それ自体)。
@tsv
生成された配列は演算子に渡され、タブで区切られたレコードに出力されます。
これを理解するために、各オブジェクトのキーが同じ方法でソートされているとしますuserinfo
。そうでない場合は、jq -S .
最初にデータを渡してキーをソートする必要があります。子オブジェクトに異なるキーセットがある場合(一部はaがあり、key3
一部は欠落する可能性がありますkey1
)、出力のフィールドにヘッダーがなく表示もないため、出力はまだ意味がない可能性があります。その何かが一つにあります。
name
より複雑な式を使用して、子オブジェクトのキー名に基づいて各フィールドのタイトルを生成できます(ユーザー名フィールドのタイトルとして使用されます)jq
。
(
[.userinfo[] | keys[]] | unique
) as $h |
# This creates the header using "name" and the unique keys
# from each sub-object:
[ "name", $h[] ],
# Now we need a "double loop" over each user object and
# the unique keys (in $h) that we extracted previously,
# basically: for each user, create an array consisting of
# the username and the value for each of the keys
# (the inner loop):
[
.userinfo as $u |
$u |
# Outer loop:
keys[] as $k |
[
# The username:
$k,
# Inner loop over the $h array, extracting
# either useful data or nothing depending on
# whether the key exists in this object.
($h[] | $u[$k][.])
]
]
| @tsv
ソートされていないと欠落/追加キーを持つ入力の例:
{
"userinfo": {
"alice": {
"key2": 2,
"key1": 1
},
"bob": {
"key1": 11,
"key2": 22
},
"mallory": {
"key1": 111,
"key3": 333
}
}
}
出力:
name key1 key2 key3
alice 1 2
bob 11 22
mallory 111 333