jq 使用简介

1. jq 介绍

工作中经常要做一些额外的 json 格式的数据处理。一般是从接口获取了数据,要做后处理从中提取某些字段。但是单独写一个 Java 程序来处理还要定义一系列 POJO,如果使用 python 来写呢虽然好一些,但也是一个接口一个脚本。
后来发现了 jq 这个工具,一开始只是用它来做 json 格式的美化,后来发现处理 json 数据还真是一把好手!
Mac 下通过 brew install jq 就能安装。下面简单枚举了一下一些简单的使用场景,主要是照着 jq 常用操作 做了一下练习。jqplay.org 这个站点也给了在线编辑器和示例供大家学习。

2. 使用操作

2.1 对 Object 操作

2.1.1 获取某个 key 的值

格式:.<key>.<key>? 表示字段可能不存在)、.<key1>.<key2>.["<key>"]

 # input:
 {"foo": 42, "bar": "less interesting data"}
 
 # command:
 .foo
 
 # output:
 42

2.1.2 获取所有 key 的名称

格式:keys

 # input:
 {"abc": 1, "abcd": 2, "Foo": 3}
 
 # command:
 keys
 
 # output:
 [
   "Foo",
   "abc",
   "abcd"
 ]

2.1.3 获取所有的值

格式:.[]

 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 .[]
 
 # output:
 "mozillazg.com"
 "mozillazg"

2.1.4 所有 value 组成的数组

格式:[.[]]

 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 [.[]]
 
 # output:
 [
   "mozillazg.com",
   "mozillazg"
 ]

2.2 数组操作

2.2.1 取出所有元素

格式:.[]

 # input:
 [{"name": "tom"}, {"name": "mozillazg"}]
 
 # command:
 .[]
 
 # output:
 {
   "name": "tom"
 }
 {
   "name": "mozillazg"
 }

2.2.2 切分

格式:.[<start>[:<end>]]

 # input:
 [{"name": "tom"}, {"name": "mozillazg"}, {"name": "jim"}]
 
 # command:
 .[0:2]
 
 # output:
 [
   {
     "name": "tom"
   },
   {
     "name": "mozillazg"
   }
 ]

2.2.3 操作 object 数组中的字段

格式:.[].<key>.[]|.<key>(管道) 或者 map(.name)

 # input:
 [{"name": "foo"},{"name": "bar"},{"name": "foobar"}]
 
 # command:
 .[].name
 
 # output:
 "foo"
 "bar"
 "foobar"

2.2.4 使用多个 filter

分隔符:,

 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 '.url, .name'
 
 # output:
 "mozillazg.com"
 "mozillazg"

2.3 高级操作

2.3.1 管道

符号:|

 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 .|.url
 
 # output:
 "mozillazg.com"

2.3.2 length 函数

2.3.2.1 对字符串
 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 .url|length
 
 # output:
 13
2.3.2.2 对数组
 # input:
 ["mozillazg.com", "mozillazg"]
 
 # command:
 .|length
 
 # output:
 2

2.3.3 map 函数

 # input:
 ["mozillazg.com", "mozillazg"]
 
 # command:
 map(length)
 
 # output:
 [
   13,
   9
 ]

2.3.4 filter 函数

 # input:
 ["mozillazg.com", "mozillazg"]
 
 # command:
 map(select(.|length > 9))
 
 # output:
 [
   "mozillazg.com"
 ]

2.3.5 join 函数

 # input:
 ["mozillazg.com", "mozillazg"]
 
 # command:
 .|join(" | ")
 
 # output:
 "mozillazg.com | mozillazg"

2.3.6 字符串拼接

 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 "hi " + .name
 
 # output:
 "hi mozillazg"

2.3.7 split 函数

 # input:
 "mozillazg.com | mozillazg"
 
 # command:
 split(" | ")
 
 # output:
 [
   "mozillazg.com",
   "mozillazg"
 ]

2.3.8 判断语句

语法:if .. then .. elif .. then .. else .. end

 # input:
 [0, 1, 2, 3]
 
 # command:
 map(if . == 0 then "zero" elif . == 1 then "one" elif . == 2 then "two" else "many" end)
 
 # output:
 [
   "zero",
   "one",
   "two",
   "many"
 ]

2.3.9 构造数组或对象

语法:[] 以及 {}

2.3.9.1 构造对象
 # input:
 ["mozillazg.com", "mozillazg"]
 
 # command:
 {name: .[1]}
 
 # output:
 {
   "name": "mozillazg"
 }
2.3.9.2 构造数组
 # input:
 {"url": "mozillazg.com", "name": "mozillazg"}
 
 # command:
 [.name, .url]
 
 # output:
 [
   "mozillazg",
   "mozillazg.com"
 ]
2.3.9.3 通过数组构造复数个对象
 # input:
 {"name": "mozillazg", "ages": [1, 2]}
 
 # command:
 {name, age: .ages[]}
 
 # output:
 {
   "name": "mozillazg",
   "age": 1
 }
 {
   "name": "mozillazg",
   "age": 2
 }

3. 参考资料

iptables 使用简介

1. 常用语法

 iptables [-t <table>] [-I|-D|-A|-C|-R|-L] <chain> -p <protocol> --dport <port> -j DROP
 
 # 追加、检查、删除规则
 iptables [-t table] {-A|-C|-D} <chain> <rule-specification>
 # 插入规则
 iptables [-t table] -I <chain> [<rulenum>] <rule-specification>
 # 替换规则
 iptables [-t table] -R <chain> <rulenum> <rule-specification>
 # 删除规则
 iptables [-t table] -D <chain> <rulenum>
 # 持久化规则
 iptables [-t table] -S [<chain> [<rulenum>]]
 # 列举规则
 iptables [-t table] -L [<chain> [<rulenum>]] [options...]
 
 rule-specification = [matches...] [target]
 match = -m <matchname> [per-match-options]
 target = -j <targetname> [per-target-options]

其中:

  • -t <table>table 默认值为 filter,包含三种内建的 chainINPUTFORWARDOUTPUT

  • -A|-C|-D|-I|-R|-S|-L-A 追加规则,-C 检查规则,-D 表示删除规则,-I 表示插入规则,-R 替换规则,-S 持久化规则, -L 列举规则。

关于 rule-specification 的部分:

  • -p <protocol>:表示协议,比如 tcpudp

  • -s <address>[/<mask>][,...]:指定来源。

  • --dport <port>:目标端口。

  • -j <targetname>:包含ACCEPTDROPRETURN

2. 使用的简单示例

通常在设计分布式的模块时,都要考虑网络或者服务器故障时的降级与异常处理。因此使用 iptables 模拟网络故障就非常必要,下面给出一个简单的例子。

 # 首先启动一个 HTTP Server
 $ python -m SimpleHTTPServer
 Serving HTTP on 0.0.0.0 port 8000 ...
 
 # 列举所有 chain 
 $ sudo iptables -L
 Chain INPUT (policy ACCEPT)
 target     prot opt source               destination
 
 Chain FORWARD (policy ACCEPT)
 target     prot opt source               destination
 
 Chain OUTPUT (policy ACCEPT)
 target     prot opt source               destination
 
 # curl 一下
 $ curl localhost:8000
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
 <title>Directory listing for /</title>
 <body>
 <h2>Directory listing for /</h2>
 <hr>
 <ul>
 <li><a href=".bash_logout">.bash_logout</a>
 <li><a href=".bashrc">.bashrc</a>
 <li><a href=".lesshst">.lesshst</a>
 <li><a href=".profile">.profile</a>
 <li><a href=".ssh">.ssh</a>
 </ul>
 <hr>
 </body>
 </html>
 
 # 禁止 8000 端口入流量
 $ sudo iptables -I INPUT -p tcp --dport 8000 -j DROP
 
 # 再列举一下所有 chain
 $ sudo iptables -L
 Chain INPUT (policy ACCEPT)
 target     prot opt source               destination
 DROP       tcp  --  anywhere             anywhere             tcp dpt:8000
 
 Chain FORWARD (policy ACCEPT)
 target     prot opt source               destination
 
 Chain OUTPUT (policy ACCEPT)
 target     prot opt source               destination
 
 # 再次 curl 一下
 $ curl localhost:8000
 curl: (7) Failed to connect to localhost port 8000: Connection timed out
 
 # 删除禁用规则
 $ sudo iptables -D INPUT -p tcp --dport 2554 -j DROP

3. 参考资料