如何使用jq将多个字段连接到同一行

13

如果我运行:

cat <file> | jq 

我得到:

{
  "user": "alex",
  "num": "486",
  "time": "Thu Jun  6 16:26:06 PDT 2019",
  "pwd": "/Users/alex/codes/ores/prompt-command",
  "pid": 11047,
  "exit_code": 0,
  "cmd": "echo '123'"
}
{
  "user": "john",
  "num": "487",
  "time": "Thu Jun  6 16:26:24 PDT 2019",
  "pwd": "/Users/alex/codes/ores/prompt-command",
  "pid": 11108,
  "exit_code": 5,
  "cmd": "echo '456'"
}
{
  "user": "alex",
  "num": "488",
  "time": "Thu Jun  6 16:26:59 PDT 2019",
  "pwd": "/Users/alex/codes/ores/prompt-command",
  "pid": 11141,
  "exit_code": 5,
  "cmd": "echo '789'"
}

但我只需要像这样的输出,而不是所有那些字段:

alex echo '123'
alex echo '789'

所以我尝试了这个:

cat <file> | jq -r '.user .cmd'

但是这并没有起作用,我得到了这个错误:

jq: error (at :63): Cannot index string with string "cmd"

我还想过滤它,只看到我的命令,类似这样:

cat <file> | jq -r '.user=alex .cmd'

仅使用 grep 是否足够?虽然不太美观,但至少可以获取您关心的两行。 - noah
2
顺便说一下,将文件名直接传递给正在运行的工具(或使用<重定向)通常是更好的形式。对于像sorttail这样受益于可寻址性的工具来说,你可以获得巨大的性能差异。(cat hugefile | tail -n 1会从头到尾读取hugefile,即使它只需要最后一行; <hugefile tail -n 1直接跳到结尾。cat somefile | sort必须按顺序从第一行到最后一行读取文件进行排序; sort <somefile可以有并行子进程对文件的子集进行排序。 - Charles Duffy
@CharlesDuffy 很好的观点,谢谢。 - Alexander Mills
2个回答

30

使用@tsv生成制表符分隔值作为输出:

jq -r '[.user, .cmd] | @tsv' <yourfile

...根据您的输入文件,发出信号:

alex    echo '123'
john    echo '456'
alex    echo '789'

...虽然如果你只过滤自己的用户账户,那么可以直接打印cmd,因为用户值是已知的:


jq -r 'select(.user == "alex") | .cmd' 

9
当您编写.user .cmd时,您正在请求.user处JSON对象的"cmd"字段。要获取.user和.cmd值,可以使用","运算符:
.user, .cmd

然而,以上方法会产生两行输出。有许多选项可用于在单行上发出多个值。您可以考虑使用字符串插值;或者将值包装在方括号中,然后使用@csv@tsvjoin/1之一;或者使用-j命令行选项。

所有这些都在标准jq文档中得到了很清楚的解释(例如参见https://stackoverflow.com/tags/jq/info),以及使用select进行选择的说明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接