如何在 shell 管道中使用`jq`?

Posted

技术标签:

【中文标题】如何在 shell 管道中使用`jq`?【英文标题】:How to use `jq` in a shell pipeline? 【发布时间】:2016-01-19 17:41:11 【问题描述】:

我似乎无法让 jq 在 shell 管道中“正常”地运行。例如:

$ curl -s https://api.github.com/users/octocat/repos | jq | cat

导致jq 简单地打印出它的帮助文本*。如果我尝试将jq 的输出重定向到文件,也会发生同样的事情:

$ curl -s https://api.github.com/users/octocat/repos | jq > /tmp/stuff.json

如果jq 确定它不是从 tty 运行,它是否会故意退出?如何防止这种行为,以便我可以在管道中使用 jq

编辑:在jq 的最新版本中,这似乎不再是问题。我现在有jq-1.6,上面的示例按预期工作。


* (我知道这个例子包含一个useless use of cat;它只是为了说明目的)

【问题讨论】:

【参考方案1】:

我发现自己也经常做的一个用例是 “我如何构造 JSON 数据以提供给其他 shell 命令,例如 curl?” 我这样做的方式是使用--null-input/-n 选项:

根本不读取任何输入!相反,过滤器使用null 作为输入运行一次。这在将 jq 用作简单的计算器或从头构造 JSON 数据时很有用。

还有一个将其传递给curl的示例:

jq -n 'key: "value"' | curl -d @- \
  --url 'https://some.url.com' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

【讨论】:

这很酷,但不确定它与这个问题有什么关系? @mgalgs 我发现自己想在 shell 管道的开头而不是在中间/末端生成/使用 jq 来过滤某些数据。 curl 示例是一个基本示例,但我发现自己经常将 JSON 数据手动输入到 curl 并尝试正确引用,所以我认为它对其他人也可能有用。【参考方案2】:

您需要提供一个过滤器作为参数。要通过未修改的 JSON,而不是默认提供的漂亮打印 jq,请使用身份过滤器 .

curl -s https://api.github.com/users/octocat/repos | jq '.' | cat

【讨论】:

我把它留在里面是因为 OP 有它;我认为它只是一个占位符,表示jq 既从管道读取又写入另一个管道。如果只想简单地查看jq 的输出,那么cat 本身是不必要的。 (1) jq 1.5 版已得到增强,因此 .在这种情况下是不必要的。 (2) 不需要引用“.”。 @peak 管道可能不需要,但我有 1.5 并且必须提供“。”将输出重定向到文件。 我出于习惯引用了.,因为我的标准做法是首先查看 JSON 的样子,然后返回并开始添加到过滤器中,这通常需要被引用。 @WalterTross 是的,我在 18 个月前的评论中解释了我引用它的原因。

以上是关于如何在 shell 管道中使用`jq`?的主要内容,如果未能解决你的问题,请参考以下文章

Python - 如何使用管道执行shell命令,但没有'shell = True'?

如何在 jq 的每次迭代中获取换行符

如何跳过jq输入中的前n个对象

如何将数据写入 Python shell 管道中第一个进程的标准输入?

php 如何利用管道(pipe)与shell互交

如何检测我的 shell 脚本是不是通过管道运行?