Phân tích cú pháp JSON trên trình bao


11

Làm cách nào tôi có thể phân tích cú pháp đầu ra JSON trên trình bao?

Ví dụ: Amazon Web Services cung cấp CLI để truy xuất trạng thái của các phiên bản của bạn:

$ aws ec2 describe-instances <my_instance_id>

Nhưng lệnh trả về một chuỗi JSON. Đầu ra của lệnh đó trông như thế này:

$ aws ec2 describe-instances x12345
{
    "Reservations" :
     {  
            "OwnerId": "1345345"
            "Groups": [], 
            "SecurityGroups": [
               {
                  "Foo" : "yes"
                  "Bar" : "no
               }
             ]
     }
}

Có một trình bao được xây dựng có thể được sử dụng để phân tích đầu ra JSON không?

Ví dụ, tôi muốn chụp trong một biến shell FOO, như sau output["Reservations"]["SecurityGroups"][0]{"Foo"}.

Trong trường hợp nó có ích, tôi đặc biệt quan tâm đến các giải pháp có thể hoạt động từ Zsh.


2
Bạn thường sẽ sử dụng một công cụ, như jshon .
jasonwryan

1
Sử dụng --output textnếu bạn muốn phân tích cú pháp trong shell mà không sử dụng các công cụ bên ngoài như thế nào jshon.
jordanm

1
@jasonwryan - Mới chỉ nghe nói jshonlần đầu tiên, tôi đã theo liên kết của bạn. Đọc xong, tôi chỉ có thể nói rằng tôi rất hài lòng rằng tôi, tình cờ, đã nghe và cài đặt jqtrước. Tôi nghĩ bạn cũng có thể muốn nghe về nó nếu bạn chưa có - nó không bận tâm với tất cả các công tắc dòng lệnh đó và có thể thực hiện các biểu thức chính của nó - thậm chí nó còn cho phép bạn khai báo các hàm và biến nếu bạn muốn. Xem câu trả lời ở đây về nó nếu bạn quan tâm.
mikeerv

Câu trả lời:


10

Theo tôi hiểu, bạn đang tìm kiếm giá trị của "Foo". Điều này thực sự dễ thực hiện với công cụ dòng lệnh shell jq. Nó giống như sedở chỗ nó thực hiện loại ngôn ngữ phân tích cú pháp riêng của mình. Cho ví dụ của bạn:

json='
{
    "Reservations" :
     {  
            "OwnerId" : "1345345",
            "Groups" :  [],
            "SecurityGroups" : [
               {
                  "Foo" : "yes",
                  "Bar" : "no"
               }
             ]
     }
}'

jqcó thể nhận được yesđơn giản như:

printf %s "$json" |
jq '.[].SecurityGroups[0].Foo?'                                                

ĐẦU RA

"yes"

Bạn có thể đi qua một danh sách từ điển hoặc danh sách từ điển bằng cách sử dụng .dotký hiệu và các mảng được lập chỉ mục có thể được lập chỉ mục đơn giản hơn, như bạn có thể đoán, các chỉ số có dấu ngoặc vuông. Trong lệnh trên, tôi sử dụng biểu mẫu chỉ mục trống để chỉ ra rằng tôi muốn tất cả các mục lặp lại của cấp đó được mở rộng. Điều đó có thể dễ hiểu hơn theo cách này:

printf %s "$json" | jq '.[][]'

... phá vỡ tất cả các giá trị cho các mục cấp hai trong hàm băm và giúp tôi ...

"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]

Điều này hầu như không làm trầy xước bề mặt liên quan đến jqkhả năng của. Nó là một công cụ vô cùng mạnh mẽ để tuần tự hóa dữ liệu trong trình bao, nó biên dịch thành một nhị phân thực thi duy nhất theo kiểu Unix cổ điển, nó rất có khả năng thông qua trình quản lý gói cho bản phân phối của bạn và nó được ghi lại rất tốt. Vui lòng truy cập của nó git-page và xem cho chính mình.

Nhân tiện, một cách khác để xử lý dữ liệu được xếp lớp json- ít nhất là để có ý tưởng về những gì bạn đang làm việc - có thể là đi theo cách khác và sử dụng .dotký hiệu để phá vỡ tất cả các giá trị ở mọi cấp độ như:

printf %s "$json" | jq '..'

{
  "Reservations": {
    "OwnerId": "1345345",
    "Groups": [],
    "SecurityGroups": [
      {
        "Foo": "yes",
        "Bar": "no"
      }
    ]
  }
}
{
  "OwnerId": "1345345",
  "Groups": [],
  "SecurityGroups": [
    {
      "Foo": "yes",
      "Bar": "no"
    }
  ]
}
"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]
{
  "Foo": "yes",
  "Bar": "no"
}
"yes"
"no"

Nhưng tốt hơn nhiều, có lẽ, sẽ chỉ là sử dụng một trong nhiều phương pháp khám phá hoặc tìm kiếm jqcung cấp cho các loại nút khác nhau.


10

Đây là một câu trả lời cho mục tiêu của bạn, nhưng không phải là câu hỏi của bạn. Có nghĩa là bạn có thể hoàn thành mục tiêu của mình mà không cần sử dụng trình phân tích cú pháp JSON.

Công cụ AWS cli có khả năng chỉ xuất các trường chọn bằng cách sử dụng --queryđối số. Điều này được ghi lại ở đây .

Ví dụ:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].GroupName' \
  --instance-id i-6b272337 \
  --output text
mongodb

Bạn thậm chí có thể chọn nhiều trường nếu bạn muốn:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14

Và bạn cũng có thể hiển thị nhiều cấu trúc phù hợp:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[*].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14
default sg-a0243bcc

1
Cảm ơn! Điều đó rất hữu ích. Tôi chấp nhận @mikeerv chủ yếu phục vụ cộng đồng với câu trả lời cho câu hỏi, nhưng câu trả lời của bạn là câu hỏi tôi sẽ sử dụng
Amelio Vazquez-Reina

Điều này rất hữu ích! Cảm ơn rât nhiều!!
MD Sayem Ahmed
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.