jqを使用してjsonの複数のフィールドを逐次解析して表示する


237

私はこのJsonを持っています

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

jqを使用して、姓名をシリアルに表示したいと思います。そのようです -

Stevie Wonder
Michael Jackson

これは私がどこまで得たかです-

jq '.users[].first, .users[].last'

しかし、それは表示されます

"Stevie"
"Michael"
"Wonder"
"Jackson"

次のことに注意してください-

  1. 不要な二重引用符。
  2. 望まない送料の返却。
  3. 乱雑です。私のクエリでは、最初にすべての名が表示され、次にすべての姓が表示されます。しかし、私は最初から最後、最後から最後のペアが欲しいです。

回答:



203

加算を使用して文字列を連結できます。

文字列は、より大きな文字列に接合されることによって追加されます。

jq '.users[] | .first + " " + .last'

上記は両方firstlastが文字列の場合に機能します。異なるデータ型(数値と文字列)を抽出する場合は、同等の型に変換する必要があります。この質問の解決策を参照してください。例えば。

jq '.users[] | .first + " " + (.number|tostring)'

41
JSON引用符を削除するには、-qオプションを付けてjqを呼び出します。例:jq -r '.users [] | 1次回+ "" + .last」
ピーク

4
+1ですが、私のユースケースでは、2つの数値を同じ行にフォーマットしようとしています。この方法は" "、数値に追加できないため失敗します。エリックの答えはこの場合により良い結果を与えます。
Synesso、2015年

9
@Synesso:動作する(.numA|tostring) + " " + (.numB|tostring)はずです。または、代わりに文字列補間を使用します"\(.numA) \(.numB)"
LS

私がやったときにjq '.users[] | .first + " " + .last'、それは非常によく働いたが、値の間に改行を引き起こした.first.last。私は変更" ""@"してからやったsed 's/@/ /g'出力として「ジョン・スミス」を取得するために出力に。このようなもの:jq '.users[] | .first + "@" + .last' | sed 's/@/ /g'
Bloodysock


14

上記の両方の回答は、key、valueが文字列の場合にうまく機能しますが、文字列と整数を追加する状況がありました(上記の式を使用したjqエラー)

要件:jsonの下にURLを構築する

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
}

解決:

curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'

閉じ括弧をエスケープする必要はなく、エラーになることに注意してください。
nymo 2017年

2
@nymo:それは逃げていません。\(...)文字列補間です。ここでは、数値.ServicePortを文字列に変換します。+標識の代わりに補間を使用して、このソリューションを短くすることができます。
LS

12

これは名前の配列を生成します

> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json

[
  "Stevie Wonder",
  "Michael Jackson"
]

4

私はこのようなことをすることで私が欲しかったものにかなり近づきました

cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 

出力はyamlに十分近いので、通常は他のツールに問題なくインポートできます。(私は基本的に入力jsonのサブセットを基本的にエクスポートする方法を探しています)


1
私の場合、この種の作品は、|をドロップするだけです 最後にtr -d '"'、jrに-rオプションを追加
user842479

4

私のアプローチは(あなたのjsonの例は整形式ではありません...それは単なるサンプルだと思います)

jq '.Front[] | [.Name,.Out,.In,.Groups] | join("|")'  front.json  > output.txt

このようなものを返します

"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"

そして、正規表現で出力をgrepします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.