jqに「現在」キーを表示

jqに「現在」キーを表示

たとえば、次のユーザー名辞書があります。

"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]あるか、キーが何個あるかに関係なく無視します。キーkey1key2それ自体)。

@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

関連情報