Оптимизация команды jq с переменными ключами. Две отдельные команды jq объединены в одну - PullRequest
1 голос
/ 30 мая 2020

У меня много разных json файлов с немного другой структурой.

Например, я мог бы получить доступ к значению LASTNAME в следующем json файле

{
  "Results": [
    {
      "Persons": [
        {
          "id": 20,
          "Position": "office employee",
          "Profession": "Office workers",
          "Address": {
            "City": "Portland",
            "State": "Washington",
            "Country": "USA"
          },
          "PersonalInfo": {
            "LASTNAME": "Pete",
            "FIRSTNAME": "Columb",
            "MIDNAME": "George"
          }
        },
        {
          "id": 21,
          "Position": "Manager",
          "Profession": "Medicine",
          "Address": {
            "City": "New York",
            "State": "",
            "Country": "USA"
          },
          "PersonalInfo": {
            "LASTNAME": "Bob",
            "FIRSTNAME": "Smith",
            "MIDNAME": ""
          }
        }
      ],
      "ItemsNumber": 2,
      "AdditionalItems": {}
    }
  ]
}

с помощью команды:

$ jq -r '. | .Results | .[] | .Persons | .[] | .PersonalInfo | .LASTNAME' question.json 

Вывод:

Pete
Bob

Второй пример файла json ($ jq -r . question2.json):

{
  "Results": [
    {
      "Persons": [
        {
          "id": 2000,
          "Position": "Director",
          "Profession": "Marketing",
          "Address": {
            "City": "Las Vegas",
            "State": "Nevada",
            "Country": "USA"
          },
          "PersonalInfo": {
            "Name1": "Steven",
            "Name2": "Bond",
            "Name3": ""
          }
        }
      ],
      "ItemsNumber": 1,
      "AdditionalItems": {}
    }
  ]
}

Команда:

jq -r '. | .Results | .[] | .Persons | .[] | .PersonalInfo | .Name2' question2.json

Вывод:

Bond

Вопрос:
Можно ли объединить эти две команды в одну и сделать ее короче (или уникальной: без разделов .Results, .Persons, .PersonalInfo доступ)?

Я пробовал следующий, например, объединить:

jq -r '. | .Results | .[] | .Persons | .[] | .PersonalInfo | (.Name2 or .LASTNAME)' question*.json

Он выводит:

true
true
true

Но я хочу:

Pete
Bob
Bond

Количество переменных ключей может быть больше двух: LASTNAME, lname, ThirdName, Name2

Обновление :
В настоящее время я не могу чтобы правильно использовать вторую команду customcommander для вывода требуемых значений без "; null; " строк, используя только jq:

cat question*.json | jq '.. | (.Address?|.City) + "; " + (.id|tostring) + "; " + (.PersonalInfo?| .LASTNAME // .Name2) | select(.)'

В этом случае вывод не очень хорош:

"; null; "
"; null; "
"Portland; 20; Pete"
"; null; "
"; null; "
"New York; 21; Bob"
"; null; "
"; null; "
"; null; "
"; null; "
"; null; "
"Las Vegas; 2000; Bond"
"; null; "
"; null; "
"; null; "

Ответы [ 2 ]

3 голосов
/ 30 мая 2020

Я думаю, вам просто нужно использовать альтернативный оператор //

. | .Results | .[] | .Persons | .[] | .PersonalInfo | .LASTNAME // .Name2

Если вам нужно сократить синтаксис, вы можете использовать:

.. | (.LASTNAME? // .Name2?) | select(.)

Но я не уверен, целесообразно это или эффективно.

0 голосов
/ 10 июня 2020

Я также использовал предложение пика, чтобы сократить команду jq для немного других требований. Я не мог правильно использовать второе предложение customcommander для объединения значений на разных уровнях файла json:

cat question*.json | jq '.Results[].Persons[] | (.Address|.City) + "; " + (.id|tostring) + "; " + (.PersonalInfo| .LASTNAME // .Name2)'
"Portland; 20; Pete"
"New York; 21; Bob"
"Las Vegas; 2000; Bond"
...