Почему выражение jq проходит через массив отдельно от другого аналогичного выражения на том же уровне? - PullRequest
1 голос
/ 01 октября 2019

У меня есть файл JSON, который выглядит следующим образом:

{
    "people": {
        "company": "Acme",
        "department": "Dev",
        "perks": {
            "eat": "pizza",
            "drink": "beer",
            "play": "twister"
        },
        "names": [{
                "last_name": "Smith",
                "first_names": [{
                        "name": "Bill",
                        "nickname": "Billy"
                    },
                    {
                        "name": "Alice",
                        "nickname": "Al"
                    },
                    {
                        "name": "Mary",
                        "nickname": "Mare"
                    }
                ]
            },
            {
                "last_name": "Brown",
                "first_names": [{
                        "name": "Gil",
                        "nickname": "Gillie"
                    },
                    {
                        "name": "Bob",
                        "nickname": "Bobby"
                    },
                    {
                        "name": "Mary",
                        "nickname": "Big M"
                    }
                ]
            },
            {
                "last_name": "Sanchez",
                "first_names": [{
                        "name": "Gil",
                        "nickname": "Gilster"
                    },
                    {
                        "name": "Jose",
                        "nickname": "Jo"
                    },
                    {
                        "name": "Marlena",
                        "nickname": "Marly"
                    }
                ]
            }
        ]
    }
}

Я ищу вывод, который выглядит следующим образом:

Acme
Dev
beer
Smith, Bill, Billy
Smith, Alice, Al
Smith, Mary, Mare
Brown, Gil, Gillie
Brown, Bob, Bobby
Brown, Mary, Big M
Sanchez, Gil, Gilster
Sanchez, Jose, Jo
Sanchez, Marlena, Marly

Я использую этот запрос:

$ jq -r '.people | .company, .department, .perks.drink, (.names[] | "\(.last_name), \(.first_names[].name), \(.first_names[].nickname)")'

и получите этот вывод, очевидно, неправильный:

Acme
Dev
beer
Smith, Bill, Billy
Smith, Alice, Billy
Smith, Mary, Billy
Smith, Bill, Al
Smith, Alice, Al
Smith, Mary, Al
Smith, Bill, Mare
Smith, Alice, Mare
Smith, Mary, Mare
Brown, Gil, Gillie
Brown, Bob, Gillie
Brown, Mary, Gillie
Brown, Gil, Bobby
Brown, Bob, Bobby
Brown, Mary, Bobby
Brown, Gil, Big M
Brown, Bob, Big M
Brown, Mary, Big M
Sanchez, Gil, Gilster
Sanchez, Jose, Gilster
Sanchez, Marlena, Gilster
Sanchez, Gil, Jo
Sanchez, Jose, Jo
Sanchez, Marlena, Jo
Sanchez, Gil, Marly
Sanchez, Jose, Marly
Sanchez, Marlena, Marly

Кажется, что .first_names[].nickname зацикливается для каждой записи .first_names[].name, производя видимый результат,но я не понимаю почему.

1 Ответ

3 голосов
/ 01 октября 2019

Ну, это случай "как он должен знать, что вы хотели?"Всякий раз, когда интерполяционное выражение \() возвращает несколько элементов, jq будет дублировать выходную строку с каждым интерполированным элементом. Если несколько интерполяций каждая делают это, то они умножаются. Он не знает, что вы хотели вместо этого параллельную итерацию.

Вы можете написать то, что вы хотите явно:

jq -r '.people | 
  .company, .department, .perks.drink, 
  (.names[] | .last_name as $last |
    .first_names[] |
    "\($last), \(.name), \(.nickname)"
  )'
...