2016-09-28 3 views
2

Это то, что мой JSON массив объектов выглядит следующим образом:Петля через объект JSON с помощью JQ

[ 
    { 
     "Description": "Description 1", 
     "OutputKey": "OutputKey 1", 
     "OutputValue": "OutputValue 1" 
    }, 
    { 
     "Description": "Description 2", 
     "OutputKey": "OutputKey 2", 
     "OutputValue": "OutputValue 2" 
    }, 
    { 
     "Description": "Description 3", 
     "OutputKey": "OutputKey 3", 
     "OutputValue": "OutputValue 3" 
    }, 
    { 
     "Description": "Description 4", 
     "OutputKey": "OutputKey 4", 
     "OutputValue": "OutputValue 4" 
    }, 
    { 
     "Description": "Description 5", 
     "OutputKey": "OutputKey 5", 
     "OutputValue": "OutputValue 5" 
    }, 
    { 
     "Description": "Description 6", 
     "OutputKey": "OutputKey 6", 
     "OutputValue": "OutputValue 6" 
    } 
] 

Как я перебирать это с помощью JQ так, что я могу использовать значение OutputKey и OutputValue в других командах?

+0

@tripleee, как автор принятого ответа на этот другой вопрос, я решил ответить на этот вопрос отдельно, потому что, перечитывая этот ответ, я не думаю, что это было особенно полезный/применимый здесь, - он потратил слишком много времени на «сорняки» того, что ОР делал неправильно, и недостаточно, чтобы обеспечить общую и применимую передовую практику. В самом деле, он предполагает, что ОП уже знает jq и сосредоточен строго на конце bash - не дает никаких указаний о том, как на самом деле перебирать массив. –

+0

@ tripleee, ... честно говоря, если есть место, чтобы закрыть его как дубликат другого, я бы почти соблазн закрыть его как дубликат, так как ответ здесь более вероятно, будет полезен другим (и вопрос здесь задается способом, способствующим такому ответу, без предварительной реализации, которая требует кучу руководства/исправления). –

+0

@tripleee, ... Я обновил другой вопрос, чтобы иметь заголовок, который лучше отражает его (не особенно обобщаемое) содержимое. –

ответ

6

Предполагая, что ваш контент поступает из in.json:

#!/usr/bin/env bash 
case $BASH_VERSION in (""|[123].*) echo "Bash 4.0 or newer required" >&2; exit 1;; esac 

declare -A values=() descriptions=() 

while IFS= read -r description && 
     IFS= read -r key && 
     IFS= read -r value; do 
    values[$key]=$value 
    descriptions[$key]=$description 
    echo "Read key $key, with value $value and description $description" >&2 
done < <(jq -r '.[] | (.Description, .OutputKey, .OutputValue)' <in.json) 

Учитывая ваш вклад, это испускает следующее STDERR:

Read key OutputKey 1, with value OutputValue 1 and description Description 1 
Read key OutputKey 2, with value OutputValue 2 and description Description 2 
Read key OutputKey 3, with value OutputValue 3 and description Description 3 
Read key OutputKey 4, with value OutputValue 4 and description Description 4 
Read key OutputKey 5, with value OutputValue 5 and description Description 5 
Read key OutputKey 6, with value OutputValue 6 and description Description 6 

Кроме того, после того, как этот код выполняется, вы можете затем выполните:

key_to_look_up="OutputKey 1" 
echo "${values[$key_to_look_up]}" 
echo "${descriptions[$key_to_look_up]}" 

... и получить в качестве вывода:

OutputValue 1 
Description 1 
+1

Обратите внимание, что '. [] | [.Описание, .OutputKey, .OutputValue] | . [] 'можно упростить до:. [] | (.Description, .OutputKey, .OutputValue) ', и даже parens можно отбросить в этом конкретном случае. – peak

+0

Хорошие баллы, спасибо! Я думаю, что парнеры добавляют ясность, поэтому я буду держать их в руках, но вы действительно помогли мне лучше понять модель jq. –

+0

(И избавление от ненужных промежуточных массивов - это улучшение во всех отношениях - как более читаемое, так и меньшее количество накладных расходов, еще раз спасибо). –

1
  1. Боюсь, что ваш вопрос не очень ясен. Если вы хотите получить значения для потребления с помощью какого-либо инструмента или приложения, отличного от jq, тогда было бы полезно узнать, что ожидает этот инструмент. Если вы хотите использовать значения в самом jq, вы можете использовать map или reduce; альтернативно, вы можете использовать фильтр, имеющий форму: .[] | ... или [.[] ...], где ... - некоторый код jq, который обращается к интересующим значениям, например.

    [.[] | [.OutputKey, .OutputValue] ] 
    
  2. Если вы хотите, чтобы выполнить какую-то операцию сокращения, то вы, вероятно, захотите использовать форму: reduce .[] as $x (_; _)

  3. Есть и другие варианты, в зависимости от того, что вы пытаетесь сделать.

+0

Я установил JSON.Я пытаюсь запустить цикл for в этом массиве и захватить значения, которые я могу передать другим функциям, которые я вызываю в цикле for. Значения, которые я хочу получить, - это использовать OutputKey. – Asdfg