Преобразовать карту строк или списков в строку значений или значения, разделенные запятыми - PullRequest
1 голос
/ 08 февраля 2020

У меня есть JSON файл:

{
  "foo": "xxx",
  "bar": ["yyy","zzz"]
}

Я хочу использовать JQ, чтобы преобразовать это в:

xxx yyy,zzz

Я пробовал разные вещи, и самое близкое, что я могу получить is:

▶ cat xx.json | jq -r 'to_entries[] | if (.value | type)=="string" then (.value) else (.value | join(",")) end' 
xxx
yyy,zzz

Обратите внимание, что я заранее не знаю имен ключей в файле JSON, и я полагаюсь на поведение to_entries для вывода записей в порядке, отсортированном по ключ (на всякий случай, если кто-то думает о том, как сделать это, что приведет к недетерминированному упорядочению вывода).

Есть ли какой-нибудь краткий способ сделать это, используя однострочник JQ?

Ответы [ 2 ]

3 голосов
/ 08 февраля 2020

Да, есть:

<file jq -r '[.foo,(.bar|join(","))]|join(" ")'

Он объединяет только два раза оба поля .foo и .bar, чтобы они были в одной строке.


Если вы не знаю имен ключей, вы можете использовать это:

<file jq -r 'to_entries|map(.value|[strings?//.[]]|join(","))|join(" ")'

Это близко к вашему решению, за исключением того, что оно использует встроенную функцию strings и оператор // и ?, чтобы избежать используя if ... then ....

1 голос
/ 08 февраля 2020

Вот решение, которое является c как по именам ключей, так и по их порядку, и является достаточно надежным в других отношениях:

jq -r 'to_entries
  | sort_by(.value|type) 
  | reverse .  # "string" before "array"
  | map(.value | if type == "array" then join(",") else tostring end)
  | join(" ")'
...