为什么`inputs'跳过输入文件的第一行?

时间:2019-05-05 20:10:09

标签: json csv jq

每当我向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 个答案:

答案 0 :(得分:2)

jq本身正在读取第一行,然后inputs(已收到该行作为输入)将读取其余部分。通常,您想使用-n选项来防止jq自己进行任何读取,而让任何inputinputs过滤器进行实际读取。

$ 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的值创建一个字典。

答案 1 :(得分:0)

@chepner对-n的解释很好,但是我想说明debug如何帮助阐明和/或揭露jq的行为。

由于每个jq程序都是一个过滤器,因此始终可以通过在debug前面加上任何echo 1 2 3 | jq 'debug | inputs' 来查看给定过滤器的输入,例如:

["DEBUG:",1]
2
3

产量:

inputs

也就是说,在这种情况下,inputs的输入为1,被-n占用,否则被忽略。

我们可以类似地检查使用echo 1 2 3 | jq -n 'debug | inputs' ["DEBUG:",null] 1 2 3 命令行选项的效果:

-n

也就是说,我们现在可以看到null选项告诉jq提供inputs作为debug的输入,而不是从STDIN获得它。

简而言之,{{1}}不仅有助于调试,而且有助于DIY理解。