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