如何使用Linux命令行工具解析和打印漂亮的JSON
JSON是一种轻量级且独立于语言的数据存储格式,易于格式化,并且易于与大多数编程语言集成,并且易于理解。
JSON一词代表JavaScript Object Notation,尽管它以JavaScript开头,主要用于在服务器和浏览器之间交换数据,但现在已用于许多领域,包括嵌入式系统。
其中我们将使用Linux上的命令行工具来解析和打印JSON。
这对于在Shell脚本中处理大型JSON数据或者在Shell脚本中处理JSON数据非常有用。
什么是漂亮的打印?
JSON数据的结构使其更具可读性。
但是,在大多数情况下,即使没有行结束符,JSON数据也存储在一行中。
显然,手动阅读和编辑不是很方便。
那时候漂亮的打印很有用。
这个名称很容易解释,重新格式化了JSON文本,使人更易读。
这就是所谓的JSON漂亮打印。
使用Linux命令行工具解析和打印漂亮的JSON
可以使用awk,sed和gerp等命令行文本处理器来解析JSON数据。
实际上,JSON.awk是执行该操作的awk脚本。
但是,有一些专用工具可以达到相同的目的。
- jq或者jshon,shell的JSON解析器,两者都很有用。
- Shell脚本(如JSON.sh或者jsonv.sh)可在bash,zsh或者破折号shell中解析JSON。
- JSON.awk,JSON解析器awk脚本。
- Python模块,例如json.tool。
- underscore-cli,Node.js和基于javascript的代码。
在本教程中,我仅关注jq,它是具有强大的JSON解析器的shell,具有高级过滤和脚本编写功能。
JSON漂亮打印
JSON数据对于人类来说可能是一种且几乎难以辨认,因此,为了使其更具可读性,此处使用了JSON漂亮打印。
示例:来自jsonip.com的数据,要获取JSON格式的外部IP地址,请使用curl或者类似以下的wget工具。
$wget -cq http://jsonip.com/-O
实际数据如下所示:
{"ip":"111.222.333.444","about":"/about","Pro!":"http://getjsonip.com"}
现在用jq漂亮地打印它:
$wget -cq http://jsonip.com/-O - | jq '.'
用jq过滤结果后,结果如下所示。
{ "ip": "111.222.333.444", "about": "/about", "Pro!": "http://getjsonip.com" }
使用python json.tool模块可以完成相同的操作。
这是一个例子:
$cat anything.json | python -m json.tool
这种基于Python的解决方案对于大多数用户来说应该是不错的选择,但是对于未预安装或者无法安装Python的系统(如在嵌入式系统上),它的用处不大。
但是json.tool python模块具有明显的优势,它是跨平台的。
因此,我们可以在Windows,Linux或者Mac OS上无缝使用它。
如何使用jq解析JSON
首先,我们需要安装jq,大多数GNU/Linux发行版已经安装了jq,并使用其各自的软件包安装程序命令进行安装。
在Arch Linux上:
$sudo pacman -S jq
在Debian,Ubuntu和Linux Mint上:
$sudo apt-get install jq
在Fedora上:
$sudo dnf install jq
在openSUSE上:
$sudo zypper install jq
对于其他操作系统或者平台,请参阅官方安装说明。
jq的基本过滤器和标识符
jq可以从stdin或者文件中读取JSON数据。
我们必须根据情况使用两者。
的单一符号。
是最基本的过滤器。
这些过滤器也称为对象标识符索引。
使用单个。
基本上与jq一起打印输入的JSON文件。
单引号我们不必总是使用单引号。
但是,如果要将多个过滤器合并在一行中,则必须使用它们。
双引号必须将任何特殊字符(如@,#,$)括在两个双引号中,例如本例中的jq .foo。
“ @ bar”
原始数据打印无论出于什么原因,如果只需要最终解析的数据(而不用双引号引起来),则可以在jq命令中使用-r标志,如下所示。
jq -r .foo.bar。
解析特定数据
要过滤掉JSON的特定部分,我们必须查看漂亮打印的JSON文件的数据层次结构。
来自Wikipedia的JSON数据示例:
{ "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ], "gender": { "type": "male" } }
在本教程中,我将使用此JSON数据作为示例,并将其另存为sample.json。
假设我要从sample.json文件中过滤出地址。
所以命令应该像这样:
$jq .address sample.json
输出示例:
{ "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }
再说一遍,我想要邮政编码,然后添加另一个对象标识符索引,例如:另一个过滤器。
$cat sample.json | jq .address.postalCode
还要注意,过滤器区分大小写,我们必须使用完全相同的字符串来获取有意义的输出,而不是null。
解析JSON数组中的元素
JSON数组的元素括在方括号内,无疑使用起来非常灵活。
要解析数组中的元素,必须使用[] identifier以及其他对象的identifier-index。
在此示例JSON数据中,电话号码存储在一个数组中,要从该数组中获取所有内容,我们仅需使用方括号,如本例所示。
$jq .phoneNumber[] sample.json
假设我们只需要数组的第一个元素,然后使用从0开始的数组对象编号,对于第一个项目,使用[0],对于下一个项目,它应该每步增加一个。
$jq .phoneNumber[0] sample.json
脚本示例
假设我只想要家庭的电话号码,而不是整个JSON数组数据。
这是使用jq命令中的脚本方便的时候。
$cat sample.json | jq -r '.phoneNumber[] | select(.type == "home") | .number'
其中我首先将一个文件管理器的结果传递给另一个,然后使用select属性选择一种特定类型的数据,再将结果传递给另一个过滤器。