2014-04-16 8 views
6

я получаю выход REST в формате JSON с помощью завивки команды, как показано нижеjq сортирует KEY и VALUES по-разному - как я могу перечислить их в том же порядке?

Получение имен ключей в одиночку с помощью:

curl http://test.te:8080/testApp/app/version | jq '.version' | jq '. | keys' 

ВЫВОД:

"Archiver-Version", 
"Build-Id", 
"Build-Jdk", 
"Build-Number", 
"Build-Tag", 
"Built-By" 

Получение ЗНАЧЕНИЯ в одиночку с помощью:

curl http://test.te.com:8080/testApp/app/version | jq '.version' | jq '.[]' 

OUTPUT (Обратите внимание, как порядок значений не соответствует порядок имен ключей; например, первое значение, "[email protected]", это значение ключа "Built-By", не так, как я ожидал бы, первый ключ, "Archiver-Version"):

"[email protected]" 
"1634d38" 
"sandbox" 
"02-03-2014-13:41" 
"testApp" 

Я пытаюсь присвоить ключи и значения для разделения массивов, так что я могу перебирать их и отображать их в формате таблицы.

Но эти две команды отсортированы по-разному, я не могу назначить значения и ключи напрямую.

Есть ли способ изменить сортировку KEYS и VALUES так, чтобы оба они были одинаковыми?

ответ

6

У jq есть возможность отсортировать ключи. См http://stedolan.github.io/jq/manual/#Invokingjq

--sort-keys/-S: 

Output the fields of each object with the keys in sorted order. 

Однако текущая выпущенная версия (1.3) из JQ не имеет такого усиления не менее, вы должны скомпилировать JQ с помощью последней версии кода от его мастер-ветви. См. http://stedolan.github.io/jq/download/, раздел «Из источника в Linux или OS X».

Для полной истории и детали этой функции см выпуск # 79 «Option или функцию для сортировки членов объекта по имени» https://github.com/stedolan/jq/issues/79

+1

'-S' /' --sort-keys', который стал доступен в версии 1.4, применим только к объектам _as a whole_, _on output_ - он не влияет на , как функции и операторы, такие как 'keys 'и' [] 'работают, которые всегда перечисляются одинаково - по-другому - поэтому здесь это не помогает. – mklement0

5

Вы можете также

$ echo '{"a":0, "b":1}' | jq -c 'to_entries|map([.key, .value])|map(.[])' 
["a",0,"b",1] 
4

Проблема вытекает из jq ' S возможно удивительное поведение по умолчанию:

  • keys перебирает ключи в алфавитном порядке Сортировка.
  • .[] перечисляет значения, основанные на порядка ввода ключи[1]

Другими словами: Если вы используете keys для извлечения ключей объекта за один проход, а затем .[] к извлеките его значения в другой, соответствующие выходные элементы могут не совпадать.

jq v1.5 ввел keys_unsorted/0 функцию, которая позволяет простое решение:

# Sample input with unordered keys. 
# Sorting the values results in the same order as sorting the keys, 
# so the output order of values below implies the key enumeration order that was applied. 
json='{ "c":3, "a":1, "b":2 }' 

печати ключи в порядке ввода, используя keys_unsorted/0:

$ echo "$json" | jq -r 'keys_unsorted[]' 
c 
a 
b 

Print значения в порядке ввода, который [] неизменно делает:

$ echo "$json" | jq -r '.[]' 
3 
1 
2 

Caveat: до версии v1.3, используя .[] в результате не гарантируется порядок перечисления (был использован ключ сортировки лежащий в основе хэш-таблицы, которая является деталью реализации); если вы все еще должны использовать v1.3, вы можете использовать подход to_entries, показанный ниже.


[v1.3 +]to_entries/0, как он используется в user2259432's helpful answer, также перечисляет свойства в порядке ввода:

# Extract keys 
$ echo "$json" | jq -r 'to_entries | map(.key)[]' 
c 
a 
b 
# Extract values 
$ echo "$json" | jq -r 'to_entries | map(.value)[]' 
3 
1 
2 

Предостережение: до v1.5, to_entries/0 Выходные пары ключ-значение в отсортированные по заказу.

Однако, поскольку to_entries/0 может быть использован для перечисления обоих ключей и значений, это еще жизнеспособным решением для получения стабильного порядка перечисления в параллельных экстракций ключ/значение, даже в предварительно v1.5 версиях.


[v1.3+] Если, наоборот, вы хотите Перечислим в отсортированность по ключ заказ:

печати ключи в алфавитном порядке порядок, используя keys/0:

$ echo "$json" | jq -r 'keys[]' 
a 
b 
c 

Распечатать значения по алфавиту отсортированным клавишам:

$ echo "$json" | jq -r 'keys[] as $k | .[$k]' 
1 
2 
3 

нюанс повторно -S/--sort-keys:

Эта опция относится только к целом объекты, на выходе:

$ echo "$json" | jq -Sc '.' 
{"a":1,"b":2,"c":3} # Sorted by key 

Это не применяются при использовании оператора или функции для доступ к внутренности объекта:

$ echo "$json" | jq -S '.[]' # !! -S doesn't apply, because [] always uses input order 
3 
1 
2 

[1] До v1.5, без определенного порядка было гарантировано, в результате чего та же проблема, однако.