Почему `input` пропускает первую строку входного файла? - PullRequest
1 голос
/ 05 мая 2019

Всякий раз, когда я предоставляю файл для jq и использую команду inputs, я получаю только все строки, кроме первой, и мне интересно, почему это

В настоящее время я использую jq 1.6 и пытаюсь использовать команду inputs для преобразования TSV (значений, разделенных табуляцией) в JSON, захватывая первую строку файла в качестве заголовков и помещая каждый заголовок в качестве ключ соответствующего значения в следующих строках

Если я выполню следующее

echo -n 'line1'$'\n''line2' | jq -R 'inputs'

Результат

line2

а не

line1
line2

как я и ожидал

В качестве обходного пути я в настоящее время добавляю новую строку ко входу, который я даю jq, как в

echo -n $'\n''line1'$'\n''line2' | jq -R 'inputs'

но я ожидаю, что смогу использовать inputs и обработать первую строку

Ответы [ 2 ]

2 голосов
/ 05 мая 2019

jq сам читает первую строку, затем inputs (получив эту строку в качестве своего входа) прочитает остаток.Как правило, вы хотите использовать параметр -n, чтобы jq не мог выполнять какое-либо чтение самостоятельно, позволяя любым фильтрам input или inputs выполнять фактическое чтение.

$ echo -n $'line1\nline2\n' | jq -nR 'inputs'
"line1"
"line2"

В вашем случаеРазрешить jq прочитать заголовок и inputs прочитать остальные данные - разумно, но вы должны сделать что-то с заголовком.Это, вероятно, сложнее, чем нужно, но выполняет работу:

$ cat tmp.tsv
foo bar baz
1   2   3
4   5   6
$ jq -R 'split("\t") as $h | [inputs | split("\t") | [{key: $h[0], value: .[0]}, {key: $h[1], value: .[1]}, {key: $h[2], value: .[2]}] | from_entries]' tmp.tsv
[
  {
    "foo": "1",
    "bar": "2",
    "baz": "3"
  },
  {
    "foo": "4",
    "bar": "5",
    "baz": "6"
  }
]

jq читает первую строку и разбивает ее на массив h, затем передает эту строку в фильтр, которыйигнорирует его, но использует inputs для чтения остальных строк, разбивая каждую из них и создавая диктат, используя (многократно) значение $h.

0 голосов
/ 06 мая 2019

@ Чепнер объяснил -n хорошо, но я хотел бы проиллюстрировать, как debug может помочь прояснить и / или демистифицировать поведение jq.

Поскольку каждая jq-программа является фильтром, всегда можно увидеть, что представляет собой вход для любого данного фильтра, предварительно добавив к нему debug, например ::

.
echo 1 2 3 | jq 'debug | inputs'

выходы:

["DEBUG:",1]
2
3

То есть, в этом случае вход для inputs равен 1, который используется inputs и в противном случае игнорируется.

Мы можем аналогичным образом изучить эффект от использования параметра командной строки -n:

echo 1 2 3 | jq -n 'debug | inputs'
["DEBUG:",null]
1
2
3

То есть теперь мы можем видеть, что опция -n указывает jq предоставить null в качестве ввода для inputs, а не получать его из STDIN.

Короче говоря, debug полезен не только для отладки, но и для самостоятельной работы.

...