JSON 是一种轻量级且与语言无关的数据存储格式,易于与大多数编程语言集成,也易于理解 。虽然它以 JavaScript 开头,而且主要用于在服务器和浏览器之间交换数据,但现在正在用于许多领域,包括嵌入式系统。JSON是前端编程经常用的格式,对于PHP或Python,解析JSON很容易,尤其是PHP的json_encode和json_decode。Linux下处理JSON的神器是jq。对于JSON格式而言,jq就像sed/awk/grep这些神器一样的方便,jq没有乱七八糟的依赖,只需要一个binary文件jq就可以了。Linux 上使用命令行工具jq来解析并格式化打印 JSON,它对于在 shell 脚本中处理大型 JSON 数据或在 shell 脚本中处理 JSON 数据非常有用。
jq 是一款命令行下处理 JSON 数据的工具,其可以接受标准输入,命令管道或者文件中的 JSON 数据,经过一系列的过滤器 (filters) 和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。jq 的这种特性使我们可以很容易地在 Shell 脚本中调用它。
二、jq 安装
jq 是开源软件。目前大部分的Linux系统官方软件仓库中均有收录。用户可以通过系统自带的软件包管理器直接安装,也可以手动从源代码编译安装。
三、jq 使用
作为一个标准的命令行工具,jq可以处理 JSON 文件,也可以直接处理从命令行管道或者流中传入的数据,这方便在 shell 脚本中使用。通过 jq 的 .(点)过滤器可以让 JSON 的格式规整起来,即输出格式化,美丽的打印效果。
1. jq 命令行帮忙信息
默认情况下,jq会将json格式化为多行树状结构输出,但有时需要将一个json串在一行输出,可使用-c参数,例如:
使用.点符号表示将输入的 JSON 文件格式化输出。
高速查询JSON数据
用逗号分隔可以同时获取json中多个key的值。但过滤出的多个值会分多行显示。要注意除了逗号之外不能有其他字符(包括空格),例如:
对于jq解析不存在的元素,会返回null的结果!!
jq 使用 --arg 参数来定义变量!!
如下uesr_name代表键,$name代表name这个变量即前面的okok,这个变量可以是交互型的
# jq --arg name okok '{uesr_name:$name}'
如下表示把shibo这个串赋给name这个变量,json的键为Name,值为name这个变量,即shibo
# jq -n --arg name shibo '{Name:$name}'
2. jq 解析并格式化输出JSON数据
使用Linux上的命令行工具jq来解析并格式化打印JSON,它对于在 shell 脚本中处理大型 JSON 数据或在 shell 脚本中处理 JSON 数据非常有用。jq可以解析特定数据,要过滤出 JSON 的特定部分,首先需要了解格式化输出的 JSON 文件的数据层次结构。
##################### jq 基本过滤和标识符功能 #####################
jq 可以从 STDIN 或文件中读取 JSON 数据,在使用中可以实际情况而定。
单个符号:. 是最基本的过滤器。这些过滤器也称为对象标识符-索引。jq 使用单个 . 过滤器基本上相当将输入的 JSON 文件格式化输出。
单引号:不必始终使用单引号。但是如果你在一行中组合几个过滤器,那么你必须使用它们。
双引号:你必须用两个双引号括起任何特殊字符,如 @、#、$,例如 jq .foo.”@bar”。
示例说明:
需要注意:
1)输入内容必须严格遵循JSON格式的标准,所有的属性名必须是以双引号包括的字符串。
2)对象的最后一个属性的末尾或者数组的最后一个元素的末尾不能有逗号,否则jq会抛出无法解析JSON的错误!
3)过滤器区分大小写 ,并且必须使用完全相同的字符串来获取有意义的输出,否则就是 null。
###### 从JSON 数组中解析元素 ######
JSON 数组的元素包含在方括号内,这无疑是非常通用的!!要解析数组中的元素,则必须使用 [] 标识符以及其他对象标识符索引。在上面第二个示例kevin文件中的JSON 数据中,电话号码存储在数组中,要从此数组中获取所有内容,只需使用括号,如下这个示例:
假设现在只想要数组的第一个元素,然后使用从 0 开始的数组对象编号,对于第一个项目,使用 [0] ,对于下一个项目,它应该每步增加 1。如下:
###### 脚本编程示例 ######
上面命令中,首先将一个过滤器的结果传递给另一个,然后使用 select 属性选择特定类型的数据,再次将结果传递给另一个过滤器。
###### jq内建函数 ######
jq 还有一些内建函数如 key,has。其中:
key 是用来获取JSON中的key元素的:
has 是用来是判断是否存在某个key:
###### jq解析案例:将sql自动部署版本包上传到制品库的检查过程 ######
3. jq 表达式
从jq 的命令行帮助中可以看出,在调用 jq 处理 JSON 数据时有一个必须的部分"jq filters"。实际上,jq 内部构建了一个简易的,功能完备的语言系统。用户在使用 jq 时,需要使用 jq 支持的语法来构建表达式(filters)并将其传给 jq。 jq 根据语法规则解析表达式并应用在输入的 JSON 数据上从而得到需要的结果。
jq 表达式支持串行化操作。一个复杂的表达式可以有多个简单的,以"|"符号分割的,串行化执行的表达式组成。每个表达式以其前边表达式的结果为输入。例如:有 JSON 数据{"name":{"firstname":"Tom","lastname":"Clancy"}}。我们要查询 lastname 属性可以使用表达式'.name|.lastname'。为了方便处理 JSON 数据,jq 提供了以下几点特性支持:
1)jq 内建了对 JSON 标准中各种数据类型的支持;
2)jq 内建了多种操作符和函数来进行数据的选择和转换;
3)jq 支持自定义函数和模块化系统。我们可以自定义自己的函数库,并在 jq 表达式中引用。
3.1 基础表达式
基础表达式(Basic filters)是 jq 提供的基本过滤器,用来访问 JSON 对象中的属性。基础表达式也是实现更复杂查询功能的基础。基础表达式主要有以下几种:
1. '.' 符号。单独的一个'.'符号用来表示对作为表达式输入的整个 JSON 对象的引用。
2. JSON 对象操作。jq 提供两种基本表达式用来访问 JSON 对象的属性:'.<attributename>'和'.<attributename>?'。正常情况下,这两个表达式的行为相同:都是访问对象属性,如果 JSON 对象不包含指定的属性则返回 null。区别在于,当输入不是 JSON 对象或数组时,第一个表达式会抛出异常。第二个表达式无任何输出。
3. 数组操作。jq 提供三种基础表达式来操作数组:
- 迭代器操作('.[]'). 该表达式的输入可以是数组或者 JSON 对象。输出的是基于数组元素或者 JSON 对象属性值的 iterator。
- 访问特定元素的操作('.[index]'或'.[attributename]')。用来访问数组元素或者 JSON 对象的属性值。输出是单个值
- 数组切片操作('.[startindex:endindex]'),其行为类似于 python 语言中数组切片操作。
4. 表达式操作(','和 '|')。表达式操作是用来关联多个基础表达式。其中逗号表示对同一个输入应用多个表达式。管道符表示将前一个表达式的输出用作后一个表达式的输入。当前一个表达式产生的结果是迭代器时,会将迭代器中的每一个值用作后一个表达式的输入从而形成新的表达式。例如'.[]|.+1', 在这个表达式中,第一个子表达式'.[]'在输入数组上构建迭代器,第二个子表达式则在迭代器的每个元素上加 1。
3.2 内置运算支持
jq 内部支持的数据类型有:数字,字符串,数组和对象(object)。并且在这些数据类型的基础上, jq 提供了一些基本的操作符来实现一些基本的运算和数据操作。列举如下:
1. 数学运算。对于数字类型,jq 实现了基本的加减乘除(/)和求余(%)运算。对于除法运算,jq 最多支持 16 位小数。
2. 字符串操作。jq 提供字符串的连接操作(运算符为'+',例如:"tom "+"jerry"结果为"tom jerry"),字符串的复制操作(例如:'a'*3 结果为'aaa'),以及字符串分割操作(将字符串按照指定的分割符分成数组,例如"sas"/"s"的结果为["","a",""],而"sas"/"a"的结果为["s","s"]。
3. 数组操作。jq 提供两种数组运算:并集('+')运算,结果数组中包含参与运算的数组的所有元素。差集运算('-'),例如:有数组 a,b, a-b 的结果为所有在 a 中且不包含在 b 中的元素组成的数组。
4. 对象操作。jq 实现了两个 JSON 对象的合并操作(merge)。当两个参与运算的对象包含相同的属性时则保留运算符右侧对象的属性值。有两种合并运算符:'+'和'*'。所不同的是,运算符'+'只做顶层属性的合并,运算符'*'则是递归合并。例如:有对象 a={"a":{"b":1}}, b={"a":{"c":2}},a+b 的结果为{"a":{"c":2}},而 a*b 的结果为{"a":{"b":1,"c":2}}
5. 比较操作:jq 内部支持的比较操作符有==, !=,>,>=,<=和<。其中,'=='的规则和 javascript 中的恒等('===')类似,只有两个操作数的类型和值均相同时其结果才是 true。
6. 逻辑运算符: and/or/not。在 jq 逻辑运算中,除了 false 和 null 外,其余的任何值都等同于 true。
7. 默认操作符('//')。表达式'a//b'表示当表达式 a 的值不是 false 或 null 时,a//b 等于 a,否则等于 b。
###### 迭代器运算 ######
jq 中有一种很特殊的运算规则:当运算符的一个或两个操作数是迭代器时,其运算以类似与笛卡尔乘积的方式进行,即把两个操作数中的每一个元素拿出来分别运算。例如:
jq 内部支持两种控制结构:判断语句和异常处理。
1)判断语句的完整结构为"if then-elif then-else-end"。当判断条件的结果为多个值时(迭代器),会对每个值执行一次判断。
2)异常处理语句的结构为"try <表达式 a> catch <表达式 b>"。当表达式 a 发生异常时,执行表达式 b,且输入为捕捉到的异常信息。如果不需要额外的处理,只是简单的抑制异常信息的输入,可以没有 catch 语句(如 try .a)。这时,整个表达式可以简写为'<表达式 a>?'(如:.a?)。
jq 内部还支持函数。在使用 jq 函数时,应该注意区分两个概念:输入和参数。输入可能是整个表达式的输入数据也可能是表达式别的部分的输出。而参数和函数一起构成新的 filter 来处理输入。和其他编程语言不同的是,在调用函数时,多个参数之间以分号分隔。jq 通过内置函数提供了数据处理时常用的操作,如过滤,映射,路径操作等。
###### 映射操作 ######
在数据处理过程中,经常需要将数据从一种形式转换成另外一种形式,或者改变数据的值。jq 提供了两个内置映射函数来实现这种转换:map 和 map_values。其中,map 处理的对象是数组,而 map_values 则处理对象属性的值。map 函数的参数为 filter 表达式。在该 filter 表达式中,'.'代表被映射的元素或值。
###### 过滤操作 ######
在 jq 中有两种类型的选择过滤操作。
第一种是基于数据类型的过滤,如表达式 '.[]|arrays' 的结果只包含数组。可以用来过滤的类型过滤器有:arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars。
第二种是 select 函数。select 接受一个条件表达式作为参数。其输入可以是迭代器,或者和 map 函数配合使用来处理数组。当输入中的某个元素使 select 参数中的条件表达式结果为真时,则在结果中保留该元素,否则不保留该元素。
###### 路径操作 ######
在 jq 中的 path 也是指从根到某个目录属性的访问路径。在 jq 中有两种表示路径的方式:数组表示法和属性表示法。属性表示法类似于在 filter 中访问某个属性值的方式,如'.a.b'。数组表示法是将路径中的每一部分表示为数组的一个元素。jq 提供了一个内置函数 path 用来实现路径从属性表示法到数组表示法的转换。
jq 还提供了函数用来读取路径的值(getpath), 设置路径的值(setpath)和删除路径(del)。不过遗憾的是,这三个函数对路径的处理并不一致。其中 getpath 和 setpath 只接受数组表示法的路径,而 del 函数只能正确处理属性表示法的路径。
jq 还提供了一个函数 paths 用来枚举可能存在的路径。在没有参数的情况下,paths 函数将输出 JSON 数据中所有可能的路径。paths 函数可以接受一个过滤器,来只输出满足条件的路径。
###### 存在判断函数 ######
jq 中提供了一系列的函数用来判断某个元素或者属性是否存在于输入数据中。其中函数 has 和 in 用来判断 JSON 对象或数组是否包含特定的属性或索引。函数 contains 和 inside 用来判断参数是否完全包含在输入数据中。对于不同的数据类型,判断是否完全包含的规则不同。对于字符串,如果 A 是 B 的子字符串,则认为 A 完全包含于 B。对于对象类型,如果对象 A 的所有属性在对象 B 中都能找到且值相同,则认为 A 完全包含于 B。
###### 数组函数 ######
除了前面讲述的基本操作符外,jq 提供内置函数用于完成数组的扁平化(flatten),反序(reverse),排序(sort, sort_by),比较(min,min_by,max,max_by) 和 查找(indices,index 和 rindex)。其中 indices 函数的输入数据可以是数组,也可以是字符串。和 index 函数不同的是,其结果是一个包含所有参数在输入数据中位置的数组。
4. jq 高级特性
4.1 变量
jq 内部支持两种变量的定义方式:
第一种定义方式:在前边 jq 的使用部分讲过,可以通过命令行参数(--arg)定义。这种方式用来从外部(如:shell)传入数据以供 filter 表达式使用。
jq 中定义变量的语句为:fiterexp as $variablename
###### 定义和使用变量 ######
jq 中同样存在变量作用域问题。在 jq 中,有两种方法分隔变量作用域:
第一种方法:用括号包围部分表达式。括号内部的表达式与外部的表达式不在同一个作用域范围内。
###### 变量作用域 ######
4.2 Reduce
jq有一种特殊的数据类型:迭代器。通常有迭代器参与的运算,其结果也是一个迭代器。jq 提供了一些特殊的语法和内置函数用来缩减迭代器运算结果的个数。
reduce 关键字用来通过运算将迭代器的所有值合并为一个值。其调用形式为:reduce <itexp> as $var (INIT; UPDATE)。其中,表达式 itexp 产生的迭代器被赋值给变量 var, UPDATE 是关于变量 var 的表达式。INIT 是该表达式的初始输入。相对于 itexp 结果中的每个元素,UPDATE 表达式被调用一次,计算出结果用作下一次 UPDATE 调用的输入。
###### reduce 关键字 ######
关键字 foreach 的作用和 reduce 类似。其调用形式为 foreach EXP as $var (INIT; UPDATE; EXTRACT)。和 reduce 关键字不同的是,foreach 关键字的每次迭代是先调用 UPDATE 再调用 EXTRACT,并以一个迭代器保留每一次的中间结果。该迭代器最后作为整个表达式的结果输出。
###### foreach 关键字 ######
内置函数 limit(n;exp)用来取得表达式 exp 结果的前 n 个值。
内置函数 first, last 和 nth。这几个函数用来取迭代器中某一个特定的元素。这几个函数既可以以函数的形式调用,也可以作为子表达式调用。
###### firs, last 和 nth ######
5. jq 自定义函数和模块化
作为一个类似于编程语言的表达式系统,jq 也提供了定义函数的能力。其语法规则为:def funcname(arguments) : funcbodyexp; 在定义函数时,需要注意下面几条规则。
- 函数名或者参数列表后面应该跟冒号以标志函数体开始。
- 如果不需要参数,可以直接把整个参数列表部分省去。
- 参数列表中,参数之间以分号(";")分隔。
- 函数体只能是一个表达式,且表达式需以分号结尾。
- 如果在表达式内部定义函数,整个子表达式部分不能只包含函数定义,否则 jq 会抛出语法错误。
在很多情况下,函数的参数都是被当作表达式引用的,类似于编程其他语言中的 callback 函数。
###### map函数 ######
如果希望传入的参数只被当作一个简单的值来使用,则需要把参数的值定义为一个同名变量,并按照使用变量的方式引用。
###### 值参数 ######
函数内部可以定义子函数。利用这个特性我们可以实现递归函数。
###### 递归函数实现数组求和 ######
除了在表达式内部定义函数外,还可以把自定义函数写在外部文件中形成单独的类库。jq 有一套完整的模块系统来支持自定义类库。
1)首先可以通过命令行参数'-L'来指定 jq 搜索模块时需要搜索的路径。
2)其次在模块内部,可以通过 import 指令和 include 指令来实现互相引用。在引用指令中,有几个特殊的路径前缀需要说明。
'~', 表示当前用户的 home 目录
'$ORIGIN',表示 jq 命令的可执行文件所在的目录
'.',表示当前目录,该前缀只能用在 include 指令中。
*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************
随着通用大语言模型的发展和智能 Agent 技术的兴起,我们正迎来 AI 应用开发的一个新时代。
有兴趣整点薯条不
一、背景在特定场景下,文件可是复印或者打印,但是内容需要为手写现使用Python将word文档内容转换为手写字体示例文档如下:二、准备使用Python第三方库docx进行处理,先安装pip install python-docx下载安装手写字体,字体决定了最终文本的手写逼真效果这里下载安装了两个手写字体:杨任东竹石体-Light, 杨任东竹石体-Regular三、代码复制文本内容遍历文档的段落,复
2.5 变量的格式化输出苹果单价 9.00 元/斤,购买了 5.00 斤,需要支付 45.00 元在 Python 中可以使用 print 函数将信息输出到控制台如果希望输出文字信息的同时,一起输出 数据,就需要使用到 格式化操作符% 被称为 格式化操作符,专门用于处理字符串中的格式包含 % 的字符串,被称为 格式化字符串% 和不同的 字符 连用,不同类型的数据 需要使用 不同的格式化字符格式化字
d中nan接下来
接下来会更难!这个是毫无疑问的了。A股在疫情后第一天开盘,千股跌停,那惨烈程度真是恐怖,股市就是资本市场对未来经济的预期。有人说,我又不炒股,跟我没啥关系。这你可就错了,倾巢之下,焉有完...
还是看书比较系统点,虽然不一定细致。之前一直膜拜“虫师”得细致,关注他,最近看了张俊清得自动化测试接下来要着手改造两件事:1:自动化实现分布式 大体思想:将用例放到queue中,主机控制启动分机(主分机得配置一样),分机从que中取用例执行,分别生成测试报告,然后拷贝每个分机上得报告到主机得报告中(报告文件设置成共享,读取文件路径,拷贝文件夹)---此处感觉会不会造成同时
print()可谓人人都会用,可是怎么用输出得漂亮一点呢?
【代码】日期格式化输出。
在某些实际场景中,我们经常需要按照一定的格式输出数据,比如输出浮点数时保留 2 位小数,再比如以十六进制的形式输出整数,输出数据
1. C++中格式ut operations.
# Java金额格式化输出在日常开发中,我们经常会涉及到金额的计算和显示,而对于金额的显示,我们往往需要格式化输出,以便让用户更加清晰地看到金额的大小。在Java中,我们可以使用`NumberFormat`类来对金额进行格式化输出。## NumberFormat类简介`NumberFormat`类是用来格式化数字的抽象基类,它提供了一些静态工厂方法来获取默认的格式化实例,也可以通过实例
一、文件对象文件对象是Python代码访问、操作磁盘上文件的主要接口。文件对象不仅可以用来访问普通的磁盘文件,而且也可以访问任何其它类型抽象层面上的 "文件"。一旦设置了合适的"钩子",你就可以访问具有文件类型接口的其它对象,就好像访问的是普通文件一样。进行这种抽象处理的主要原因是许多的输入/输出数据结构更趋向于使用通用的接口。这样就可以在程序行为和实现上保持一致性。文件只是连续的字节序列(字符串
print() 函数使用以 % 开头的转换说明符对各种类型的数据进行格式化输出。 转换说明符(Conversion Specifier)只是一个占位符(也称为格式化操作符),它会被后面表达式(变量、常量、数字、字符串、加减乘除等各种形式)的值代替。 转换说明符 解释%d、%i 转换为带符号的十进制整 ...
Pinely Round 5 (Div. 1 + Div. 2) A. Round Trip 【题目】 参加cf比赛,分两类div1 div2, div1对所有人rated, div2只对<X的rated。 你可以主动选择在rated的场次加分或者减分,如果当前场次能够rated,当前分为R,则变动 ...
Docker数据持久化方式对比及命令解析 容器删除后数据的去向 默认情况下,容器删除时其可写层数据会丢失。只有使用外部存储方式的数据才会保留,主要包括: Volume(Docker管理的专用数据目录) Bind Mount(直接挂载宿主机路径) Tmpfs Mount(仅内存存储) 三种持久化方式对比 特性 Volume Bind Mount Tmpfs 存储位置 Docker管理 宿主机指定路径 内存 容器删除后保留 ✅ ✅ ❌ 多容器共享 ✅ ✅ ❌ 速度 中等 中等 极快 命令解析 -v(简写)和--
modprobe命令 与 KVM模块 笔记251006modprobe 是 Linux 系统中一个非常重要的内核模块管理命令。它用于动态地向运行中的内核添加或移除模块。下面我将为你详细讲解这个命令。 1. 什么是内核模块?简单来说,内核模块是一段可以在运行时动态加载到内核或从内核卸载的代码。它扩展了 ...
摘要:中国18位身份证号码校验遵循GB11643-1999标准,最后一位校验码通过前17位计算得出。核心算法包括:前17位数字分别乘以固定加权因子后求和,取模11得到余数,再按对应表转换为校验码(含字母X)。完整校验还需验证行政区划码、出生日期合法性及顺序码性别标识。提供JavaScript实现代码,包含基本校验函数和完整校验函数(含行政区划和日期验证),注意15位身份证需先升级,校验码X需大写。其他注意事项包括行政区划码范围和日期有效性验证。