jq «объект не может быть отформатирован в формате tsv, только массив» при создании таблицы из данных json - PullRequest
3 голосов
/ 29 января 2020

Мой сценарий создает набор данных json и затем пытается представить его в виде таблицы.

В выводе для первой строки кода вы можете увидеть пример набора данных:

echo $ {conn_list [@]} | jq '.'

{
  "host": {
    "name": "mike1",
    "node": "c04",
    "s_ip": "10.244.7.235",
    "s_port": "38558",
    "d_ip": "129.12.34.567",
    "d_port": "22",
    "pif_ip": "129.23.45.678",
    "pif_port": "11019"
  }
}
{
  "host": {
    "name": "fhlb-test",
    "node": "c04",
    "s_ip": "10.244.7.20",
    "s_port": "49846",
    "d_ip": "129.98.76.543",
    "d_port": "22",
    "pif_ip": "129.87.65.432",
    "pif_port": "23698"
  }
}

Я использую следующую команду jq с @tsv, чтобы попытаться построить и заполнить таблицу, но сталкиваюсь с этой ошибкой:

echo $ {conn_list [@]} | jq -r '["NAME", "NODE", "SOURCE IP", "SOURCE PORT", "DESTINATION IP", "DESTINATION PORT", "GATEWAY IP", "GATEWAY PORT"], (. [], map (длина * "-")), (. [] | [.name, .node, .s_ip, .s_port, .d_ip, .d_port, .pif_ip, .pif_port]) | @ tsv '

NAME    NODE    SOURCE IP       SOURCE PORT     DESTINATION IP  DESTINATION PORT        GATEWAY IP      GATEWAY PORT
jq: error (at <stdin>:1): object ({"name":"mi...) cannot be tsv-formatted, only array
NAME    NODE    SOURCE IP       SOURCE PORT     DESTINATION IP  DESTINATION PORT        GATEWAY IP      GATEWAY PORT
jq: error (at <stdin>:1): object ({"name":"fh...) cannot be tsv-formatted, only array

Моя цель состоит в том, чтобы в таблице была только одна строка заголовка столбца, а не одна для каждой записи, и, конечно, отображать данные вместо ошибки. Бит '(. [], Map (length * "-")) "предназначен для автоматической генерации штрихов правильного размера для отделения заголовков столбцов от данных. Кто-нибудь видит, что я делаю не так? :)

1 Ответ

3 голосов
/ 29 января 2020

Фиксированная версия может выглядеть следующим образом:

jq -rn '
# Assign the list of fields to a variable
["NAME","NODE","SOURCE IP","SOURCE PORT","DESTINATION IP","DESTINATION PORT","GATEWAY IP","GATEWAY PORT"] as $fields |
(
  $fields,                        # emit the list as a header
  ($fields | map(length*"-")),    # print separators below each header
  (inputs | .[] | [.name, .node, .s_ip, .s_port, .d_ip, .d_port, .pif_ip, .pif_port])
) | @tsv' <<<"$s" # where s is a string with your JSON content.

... который выдает в качестве вывода для вашего ввода (без переформатирования для выравнивания вкладок):

NAME    NODE    SOURCE IP   SOURCE PORT DESTINATION IP  DESTINATION PORT    GATEWAY IP  GATEWAY PORT
----    ----    ---------   ----------- --------------  ----------------    ----------  ------------
mike1   c04 10.244.7.235    38558   129.12.34.567   22  129.23.45.678   11019
fhlb-test   c04 10.244.7.20 49846   129.98.76.543   22  129.87.65.432   23698

Непосредственной ошибкой было включение .[] в (.[], map(length*"-")) - первая часть этого бессмысленна и ничего не делает, кроме как вставляет содержимое вашей карты (которое недопустимо в содержимом TSV, не является списком) в поток данных .

...