如何使用 jq 在 Linux 命令行上解析 JSON 文件如何使用 jq 在 Linux 命令行上解析 JSON 文件如何使用 jq 在 Linux 命令行上解析 JSON 文件如何使用 jq 在 Linux 命令行上解析 JSON 文件
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何使用 jq 在 Linux 命令行上解析 JSON 文件

JSON 是用于在网络上传输基于文本的数据的最流行格式之一。它无处不在,你一定会遇到它。我们将向您展示如何使用 jq 命令从 Linux 命令行处理它。

JSON 和 jq

JSON 代表 JavaScript 对象表示法。这是一种允许以自描述方式将数据编码为纯文本文件的方案。 JSON 文件中没有注释——内容应该是不言自明的。每个数据值都有一个称为“名称”或“键”的文本字符串。这告诉您数据值是什么。它们一起被称为名称:值对,或键:值对。冒号 (:) 将键与其值分开。

“对象”是键值对的集合。在 JSON 文件中,对象以左大括号 ({) 开头,以右大括号 (}) 结尾。 JSON 还支持“数组”,它们是有序的值列表。数组以左括号 ([) 开头,以右括号 (]) 结尾。

当然,从这些简单的定义中,可以产生任意的复杂性。例如,对象可以嵌套在对象中。对象可以包含数组,数组也可以包含对象。所有这些都可以有开放式的嵌套级别。

但在实践中,如果 JSON 数据的布局很复杂,数据布局的设计可能应该重新考虑。当然,如果您不生成 JSON 数据,只是尝试使用它,那么您对其布局没有发言权。不幸的是,在这些情况下,您只需要处理它。

大多数编程语言都有允许它们解析 JSON 数据的库或模块。遗憾的是,Bash shell 没有这样的功能。

需求是发明之母,jq 实用程序诞生了!使用 jq,我们可以在 Bash shell 中轻松解析 JSON,甚至将 XML 转换为 JSON。无论您是必须使用精心设计的、优雅的 JSON,还是由噩梦构成的东西,都无关紧要。

如何安装jq

我们必须在用于研究本文的所有 Linux 发行版上安装 jq。

要在 Ubuntu 上安装 jq,请键入以下命令:

sudo apt-get install jq

要在 Fedora 上安装 jq,请键入以下命令:

sudo dnf install jq

要在 Manjaro 上安装 jq,请键入以下命令:

sudo pacman -Sy jq

如何使 JSON 可读

JSON 不关心空格,布局也不影响它。只要遵循 JSON 语法规则,处理 JSON 的系统就可以读取和理解它。正因为如此,JSON 通常作为一个简单的长字符串传输,而不考虑任何布局。这节省了一点空间,因为制表符、空格和换行符不必包含在 JSON 中。当然,所有这一切的缺点是当人们试图阅读它时。

让我们从 NASA 网站中提取一个简短的 JSON 对象,告诉我们国际空间站的位置。我们将使用 curl,它可以下载文件来为我们检索 JSON 对象。

我们不关心 curl 通常生成的任何状态消息,因此我们将使用 -s(无声)选项键入以下内容:

curl -s http://api.open-notify.org/iss-now.json

现在,稍加努力,您就可以阅读本文。您必须挑选出数据值,但这并不容易或不方便。让我们重复一遍,但这次我们将通过 jq 进行管道传输。

jq 使用过滤器来解析 JSON,这些过滤器中最简单的是句点 (.),意思是“打印整个对象”。默认情况下,jq 漂亮地打印输出。

我们将它们放在一起并键入以下内容:

curl -s http://api.open-notify.org/iss-now.json | jq .

那好多了!现在,我们可以确切地看到发生了什么。

整个对象包裹在花括号中。它包含两个键:名称对:message 和 timestamp。它还包含一个名为 iss_position 的对象,该对象包含两个键值对:longitude 和 latitude。

我们会再试一次。这次我们将输入以下内容,并将输出重定向到一个名为“iss.json”的文件中:

curl -s http://api.open-notify.org/iss-now.json | jq . > iss.json
cat iss.json

这在我们的硬盘上为我们提供了一个布局良好的 JSON 对象副本。

访问数据值

正如我们在上面看到的,jq 可以从 JSON 中提取通过管道传输的数据值。它还可以处理存储在文件中的 JSON。我们将使用本地文件,这样命令行就不会被 curl 命令弄得乱七八糟。这应该使它更容易理解。

从 JSON 文件中提取数据的最简单方法是提供一个键名来获取其数据值。键入句点和键名,两者之间不要有空格。这会根据键名创建一个过滤器。我们还需要告诉 jq 使用哪个 JSON 文件。

我们键入以下内容以检索 message 值:

jq .message iss.json

jq 在终端窗口中打印 message 值的文本。

如果您的键名包含空格或标点符号,则必须将其过滤器用引号引起来。通常注意只使用字符、数字和下划线,这样 JSON 键名就不会出现问题。

首先,我们键入以下内容来检索 timestamp 值:

jq .timestamp iss.json

时间戳值被检索并打印在终端窗口中。

但是我们如何访问 iss_position 对象中的值呢?我们可以使用 JSON 点表示法。我们将在键值的“路径”中包含 iss_position 对象名称。为此,密钥所在对象的名称将位于密钥本身的名称之前。

我们键入以下内容,包括 latitude 键名(注意“.iss_position”和“.latitude”之间没有空格):

jq .iss_position.latitude iss.json

要提取多个值,您必须执行以下操作:

  • 在命令行中列出键名。
  • 用逗号分隔 (,)。
  • 将它们括在引号 (\) 或撇号 () 中。

考虑到这一点,我们输入以下内容:

jq ".iss_position.latitude, .timestamp" iss.json

这两个值打印到终端窗口。

使用数组

让我们从 NASA 获取一个不同的 JSON 对象。

这一次,我们将使用目前在太空中的宇航员名单:

curl -s http://api.open-notify.org/astros.json

好的,那行得通,所以让我们再做一次。

我们将键入以下内容以通过 jq 将其通过管道传输并将其重定向到名为“astro.json”的文件:

curl -s http://api.open-notify.org/astros.json | jq . > astro.json

现在让我们输入以下内容来检查我们的文件:

less astro.json

如下图,我们现在看到了太空中的宇航员名单,以及他们乘坐的飞船。

此 JSON 对象包含一个名为 people 的数组。我们知道它是一个数组,因为左括号 ([)(在上面的屏幕截图中突出显示)。它是一个对象数组,每个对象包含两个键值对:name 和 craft。

就像我们之前所做的那样,我们可以使用 JSON 点表示法来访问这些值。我们还必须在数组名称中包含方括号 ([])。

考虑到所有这些,我们输入以下内容:

jq ".people[].name" astro.json

这一次,所有名称值都打印到终端窗口。我们要求 jq 做的是打印数组中每个对象的名称值。很整洁吧?

如果我们在命令行中将其在数组中的位置放在方括号 ([]) 中,我们就可以检索单个对象的名称。该数组使用零偏移索引,这意味着数组第一个位置的对象为零。

要访问数组中的最后一个对象,您可以使用 -1;要获取数组中的倒数第二个对象,可以使用 -2,依此类推。

有时,JSON 对象会提供数组中元素的数量,这一个就是这种情况。除了数组之外,它还包含一个名为 number 的键:名称对,值为 6。

此数组中包含以下数量的对象:

jq ".people[1].name" astro.json
jq ".people[3].name" astro.json
jq ".people[-1].name" astro.json
jq ".people[-2].name" astro.json

您还可以在数组中提供开始和结束对象。这称为“切片”,可能有点令人困惑。请记住,数组使用零偏移量。

要从索引位置 2 检索对象,直到(但不包括)索引位置 4 的对象,我们键入以下命令:

jq ".people[2:4]" astro.json

这将打印数组索引二(数组中的第三个对象)和索引三(数组中的第四个对象)处的对象。它在数组索引 4 处停止处理,这是数组中的第五个对象。

更好地理解这一点的方法是在命令行上进行试验。您很快就会看到它是如何工作的。

如何使用带过滤器的管道

您可以将输出从一个过滤器传输到另一个过滤器,而不必学习新符号。与 Linux 命令行相同,jq 使用竖线 (|) 表示管道。

我们将告诉 jq 将 people 数组通过管道传输到 .name 过滤器中,该过滤器应在终端窗口中列出宇航员的姓名。

我们键入以下内容:

jq ".people[] | .name" astro.json

创建数组和修改结果

我们可以使用 jq 来创建新的对象,比如数组。在此示例中,我们将提取三个值并创建一个包含这些值的新数组。请注意左括号 ([) 和右括号 (]) 也是过滤器字符串中的第一个和最后一个字符。

我们键入以下内容:

jq "[.iss-position.latitude, iss_position.longitude, .timestamp]" iss.json

输出包含在方括号中并用逗号分隔,使其成为一个格式正确的数组。

数值也可以在检索时进行操作。让我们从 ISS 位置文件中提取 timestamp,然后再次提取它并更改返回的值。

为此,我们键入以下内容:

jq ".timestamp" iss.json
jq ".timestamp - 1570000000" iss.json

如果您需要在值数组中添加或删除标准偏移量,这将很有用。

让我们输入以下内容来提醒自己 iss.json 文件包含的内容:

jq . iss.json

假设我们想要摆脱 message 键值对。它与国际空间站的位置没有任何关系。它只是一个标志,表示位置已成功检索。如果它超出要求,我们可以免除它。 (你也可以忽略它。)

我们可以使用 jq 的删除函数 del() 来删除键值对。要删除消息键值对,我们键入以下命令:

jq "del(.message)" iss.json

请注意,这实际上并没有从“iss.json”文件中删除它;它只是将其从命令的输出中删除。如果您需要创建一个不包含 message 键值对的新文件,请运行该命令,然后将输出重定向到一个新文件中。

更复杂的 JSON 对象

让我们检索更多 NASA 数据。这一次,我们将使用一个 JSON 对象,其中包含来自世界各地的流星撞击地点的信息。这是一个更大的文件,具有比我们之前处理的文件复杂得多的 JSON 结构。

首先,我们将键入以下内容以将其重定向到名为“strikes.json”的文件:

curl -s https://data.nasa.gov/resource/y77d-th95.json | jq . > strikes.json

要查看 JSON 的外观,我们键入以下内容:

less strikes.json

如下所示,文件以左括号 ([) 开头,因此整个对象是一个数组。数组中的对象是键值对的集合,并且有一个名为 geolocation 的嵌套对象。 geolocation 对象包含更多键值对,以及一个名为 coordinates 的数组。

让我们从索引位置 995 到数组末尾的对象中检索流星撞击的名称。

我们将键入以下内容以通过三个过滤器对 JSON 进行管道传输:

jq ".[995:] | .[] | .name" strikes.json

过滤器以下列方式发挥作用:

  • .[995:]:这告诉 jq 处理从数组索引 995 到数组末尾的对象。冒号后没有数字 (:) 告诉 jq 继续到数组的末尾。
  • .[]:这个数组迭代器告诉 jq 处理数组中的每个对象。
  • .name:此过滤器提取名称值。

稍作改动,我们就可以从数组中提取最后 10 个对象。 “-10”指示 jq 开始处理数组末尾后 10 处的对象。

我们键入以下内容:

jq ".[-10:] | .[] | .name" strikes.json

正如我们在前面的示例中所做的那样,我们可以键入以下内容来选择单个对象:

jq ".[650].name" strikes.json

我们还可以对字符串应用切片。为此,我们将键入以下内容以请求数组索引 234 处对象名称的前四个字符:

jq ".[234].name[0:4]" strikes.json

我们还可以完整地看到一个特定的对象。为此,我们键入以下内容并包含一个没有任何键:值过滤器的数组索引:

jq ".[234]" strikes.json

如果只想查看值,可以在不查看键名的情况下执行相同的操作。

对于我们的示例,我们键入以下命令:

jq ".[234][]" strikes.json

要从每个对象中检索多个值,我们在以下命令中用逗号分隔它们:

jq ".[450:455] | .[] | .name, .mass" strikes.json

如果要检索嵌套值,则必须标识构成它们“路径”的对象。

例如,要引用 coordinates 值,我们必须包含包罗万象的数组、geolocation 嵌套对象和嵌套的 coordinates 数组, 如下所示。

要查看数组索引位置 121 处对象的 坐标 值,我们键入以下命令:

jq ".[121].geolocation.coordinates[]" strikes.json

长度函数

jq length 函数根据应用的内容给出不同的指标,例如:

  • Strings:字符串的长度,以字节为单位。
  • 对象:对象中键值对的数量。
  • Arrays:数组中数组元素的个数。

以下命令返回 JSON 数组中 10 个对象中 name 值的长度,从索引位置 100 开始:

jq ".[100:110] | .[].name | length" strikes.json

要查看数组中第一个对象中有多少键值对,我们键入以下命令:

jq ".[0] | length" strikes.json

按键功能

您可以使用 keys 函数来了解您要使用的 JSON。它可以告诉您键的名称是什么,以及数组中有多少个对象。

要在“astro.json”文件的 people 对象中查找键,我们键入以下命令:

jq ".people.[0] | keys" astro.json

要查看 people 数组中有多少元素,我们键入以下命令:

jq ".people | keys" astro.json

这表明有六个零偏移数组元素,编号为零到五。

has() 函数

您可以使用 has() 函数来查询 JSON 并查看对象是否具有特定的键名。请注意,键名必须用引号引起来。我们将过滤器命令用单引号 () 括起来,如下所示:

jq '.[] | has("nametype")' strikes.json

数组中的每个对象都被选中,如下所示。

如果要检查特定对象,请将其索引位置包含在数组过滤器中,如下所示:

jq '.[678] | has("nametype")' strikes.json

没有它就不要靠近 JSON

jq 实用程序是专业、强大、快速的软件的完美示例,它让 Linux 世界的生活变得如此愉快。

这只是对该命令的常用功能的简要介绍——还有很多。如果您想深入了解,请务必查看全面的 jq 手册。

Linux Commands
Files tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc
Processes alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap
Networking netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld

RELATED: Best Linux Laptops for Developers and Enthusiasts

©2015-2025 艾丽卡 support@alaica.com