Подтвердить что ты не робот

Как сопоставить объект с массивами, чтобы его можно было преобразовать в csv?

Я пытаюсь преобразовать объект, который выглядит так:

{
  "123" : "abc",
  "231" : "dbh",
  "452" : "xyz"
}

В csv, который выглядит следующим образом:

"123","abc"
"231","dbh"
"452","xyz"

Я бы предпочел использовать инструмент командной строки jq, но, похоже, не может понять, как выполнить назначение. Мне удалось получить ключи с jq '. | keys' test.json, но не могли понять, что делать дальше.

Проблема в том, что вы не можете преобразовать объект k: v, подобный этому, прямо в csv с помощью @csv. Он должен быть массивом, поэтому нам нужно сначала преобразовать в массив. Если бы клавиши были названы, это было бы просто, но они динамичны, поэтому это не так просто.

4b9b3361

Ответ 1

Попробуйте этот фильтр:

to_entries[] | [.key, .value]
  • to_entries преобразует объект в массив объектов key/value. [] разбивает массив на каждый из элементов массива
  • затем для каждого из элементов, скрытых для массива, содержащего ключ и значение.

Это приводит к следующему выводу:

[
  "123",
  "abc"
],
[
  "231",
  "dbh"
],
[
  "452",
  "xyz"
]

Затем вы можете использовать фильтр @csv для преобразования строк в строки CSV.

$ echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries[] | [.key, .value] | @csv'
"123","abc"
"231","dbh"
"452","xyz"

Ответ 2

Вот пример, который я использовал сегодня утром (обработка оповещений PagerDuty):

cat /tmp/summary.json | jq -r '
  .incidents
  | map({desc: .trigger_summary_data.description, id:.id})
  | group_by(.desc)
  | map(length as $len
  | {desc:.[0].desc, length: $len}) 
  | sort_by(.length) 
  | map([.desc, .length] | @csv)
  | join("\n") '

Сбрасывает документ, разделенный CVS, который выглядит примерно так: "[Triggered] Something annoyingly frequent",31 "[Triggered] Even more frequent alert!",35 "[No data] Stats Server is probably acting up",55

Ответ 3

Ответ Джеффа - хорошая отправная точка, что-то ближе к ожидаемому:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))'

[
 "123,abc",
 "231,dbh",
 "452,xyz"
]

Но не удалось найти способ соединения с использованием новой строки:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))|join("\n")'

"123,abc\n231,dbh\n452,xyz"

Ответ 4

onecol2txt () {
 awk 'BEGIN { RS="_end_"; FS="\n"}
   { for (i=2; i <= NF; i++){
       printf "%s ",$i 
       }
     printf "\n" 
   }'
}
cat jsonfile | jq -r -c '....,"_end_"' | onecol2txt