前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正则表达式介绍与使用

正则表达式介绍与使用

作者头像
全栈工程师修炼指南
发布2022-09-28 21:27:27
3400
发布2022-09-28 21:27:27
举报
文章被收录于专栏:全栈工程师修炼之路

[TOC]

0x00 前言简述

Q: 什么是模板? 答: MVC 框架(Model View Controller): Model(模型,通常在服务端)用于处理数据、View(视图,客户端代码)用于展现结果、Controller(控制器)用于控制数据流,确保 M(模型改变) 和 V(视图) 的同步,即一旦 M 改变,V 也应该同步更新。

常常对于 View 端的处理,在很多动态语言中是通过在静态 HTML 代码中插入动态数据来实现的。由于最终展示给用户的信息大部分是静态不变的,只有少部分数据会根据用户的不同而动态生成, 所以将静态信息固化为模板可以复用代码,提高展示效率; 例如:JSP 的 <%=....=%> 和 PHP 的 <?php.....?>语法。

Go语言提供了简单灵活的模板支持,而基于 Go 开发的 Docker 继承了该强大能力,使其可以脱离 Shell 的相关操作,直接对结果进行格式化输出。 比如,对于 docker ls 的输出信息会根据附加参数的不同而不同,但其表头信息是固定的, 并且所有支持 –format 扩展的 Docker CLI 指令以及kubectl查看相关命令均支持该操作。

0x01 基础语法

描述: 下面列举出Go模板的常用用法并进行简单的演示;

1.注释
代码语言:javascript
复制
# 格式: `{{/*注释内容*/}}`
docker inspect --format='{{/*查看容器的默认网关*/}}' $INSTANCE_ID
docker inspect --format='{{/*查看容器的默认网关*/}}{{.NetworkSettings.Networks.opt_default.Gateway}}' dc1
#172.18.0.1
2.打印信息

描述: Go template 中利用 go 语言的 print 函数对模板中的字符串进行输出, go中还包括两种相似println 和 printf等内置函数。

  • print: 将传入的对象转换为字符串并写入到标准输出中。如果后跟多个参数,输出结果之间会自动填充空格进行分隔。
  • println:功能和 print 类似,但会在结尾添加一个换行符。也可以直接使用 来换行。
  • printf: 与 shell 等环境一致,可配合占位符用于格式化输出。

基础示例:

代码语言:javascript
复制
# 示例1
docker inspect --format '{{.State.Pid}} {{.State.ExitCode}}' $INSTANCE_ID
# 24039 0

# 示例2
docker inspect --format '{{print .State.Pid .State.ExitCode}}' $INSTANCE_ID
# 24039 0

# 示例3
docker inspect --format '{{.State.Pid}}{{println}}{{/*println 表示换行*/}}{{.State.ExitCode}}' $INSTANCE_ID
# 15516
# 0

# 示例7
docker inspect --format '{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}' $INSTANCE_ID
# Pid:24039 ExitCode:0
3.变量

系统变量 描述:通过下面的符号组合获取当前对象,因为点号表示当前对象及上下文,和 Java、C++ 中的 this 类似,另外如果返回结果也是一个 Struct 对象(Json 中以花括号/大括号包含),则可以直接通过点号级联调用,获取子对象的指定属性值。

注意: 如果需要获取的属性名称包含点号(比如下列示例数据)或者以数字开头,则不能直接通过级联调用获取信息。因为属性名称中的点号会被解析成级联信息,进而导致返回错误结果。即便使用引号将其包含也会提示语法格式错误。此时,需要通过 index 来读取指定属性信息。

代码语言:javascript
复制
#  组合:`{{.}}`
"Options": {
    "com.docker.network.bridge.default_bridge": "true",
    "com.docker.network.bridge.enable_icc": "true",
    "com.docker.network.bridge.enable_ip_masquerade": "true",
    "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
    "com.docker.network.bridge.name": "docker0",
    "com.docker.network.driver.mtu": "1500"
},

基础实例:

代码语言:javascript
复制
# 示例1、可以通过级联调用直接读取子对象 State 的 Status 属性,以获取容器的状态信息:
docker inspect --format '{{/*读取容器状态*/}}{{.State.Status}}' $INSTANCE_ID   

# 示例2、直接级联调用会提示找不到数据:
docker inspect --format '{{.Options.com.docker.network.driver.mtu}}' bridge
<no value>
# 用引号括起来会提示语法错误:
docker inspect --format '{{.Options."com.docker.network.driver.mtu"}}' bridge
Template parsing error: template: :1: bad character U+0022 '"'
# 正确的用法,必须用 index 读取指定属性名称的属性值:
docker inspect --format '{{/*读取网络在hosts上的名称*/}}{{index .Options "com.docker.network.bridge.name"}}' bridge
docker0

自定义变量 描述:可以在处理过程中设置自定义变量,然后结合自定义变量做更复杂的处理。如果自定义变量的返回值是对象,则可以通过点号进一步级联访问其属性。比如 。

基础实例:

代码语言:javascript
复制
# 示例1.结合变量的使用,对输出结果进行组装展现,以输出容器的所有绑定端口列表:
docker inspect --format '{{.NetworkSettings.Ports}}' dc1
# map[80/tcp:[{0.0.0.0 8081}]]
# "Ports": {
#   "80/tcp": [
#       {
#           "HostIp": "0.0.0.0",
#           "HostPort": "8081"
#       }
docker inspect --format '{{/*通过变量组合展示容器绑定端口列表*/}}已绑定端口列表:{{println}}{{range $p,$conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{println}}{{end}}' dc1  #注意Index指令与range结合
# 示例输出信息
已绑定端口列表:
80/tcp -> 32770
8081/tcp -> 8081
4.索引

描述:如果返回结果是一个 map, slice, array 或 string,则可以使用 index 加索引序号(从零开始计数)来读取属性值。

基础示例:

代码语言:javascript
复制
# docker inspect $INSTANCE_ID 查看容器绑定的端口信息,其 Config 属性就是一个 Map,包含了所有子网信息。
...
 "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.31.254.1/24",
                    "Gateway": "172.31.254.1"
                }
            ]
        },    

"Ports": {
      "80/tcp": [
          {
              "HostIp": "0.0.0.0",
              "HostPort": "8081"
          }
      ]
  },
...

# 示例1.通过索引序号读取默认网关
docker inspect bridge --format '{{/*查看网络的默认网关*/}}{{(index .IPAM.Config 0).Gateway}}'

# 示例2.通过索引序号读取主机映射端口
docker inspect dc1 --format '{{/*查看主机映射端口*/}}{{(index .NetworkSettings.Ports "80/tcp" 0).HostPort}}' #注意:带有数字或者点号的对象必须用""将其包括
8081
5.条件判断

描述: 与其他一些编程语言一样,利用基本判断和if .. else .. end以及判断条件进行组合判断;

基础语法:

代码语言:javascript
复制
# 判断条件
{{if pipeline}}{{end}}
{{if pipeline}}{{else}}{{if pipeline}}{{end}}{{end}} # 内部嵌套判断
{{if pipeline}}{{else if pipeline}}{{else}}{{end}}   # 多层判断

# 基础判断
{{if not .State.Restarting}}{{/*条件为真执行*/}}{{end}}
{{or .State.Status .State.Restarting}}
{{if 判断条件 .Var1 .Var2}}{{/*为真时候执行*/}}{{else}}{{/*为假时候执行*/}}{{end}}

基础判断说明:

1) not: 返回单一参数的布尔否定值,即返回输入参数的否定值。

代码语言:javascript
复制
# 如果容器的 restarting 设置为 false,则返回信息“容器没有配置重启策略”
docker inspect --format '{{if not .State.Restarting}}容器没有配置重启策略{{end}}' $(docker ps -q)
容器没有配置重启策略
容器没有配置重启策略

2) or: 除了 null(空)和 false 被识别为 false,其它值(字符串、数字、对象等)均被识别为 true。

代码语言:javascript
复制
- `{{or x y}}`: 表示如果 x 为真返回 x,否则返回 y。
- `{{or x y z}}`:后面跟多个参数时会逐一判断每个参数,并返回第一个非空的参数。`如果都为 false,则返回最后一个参数`。

docker inspect --format '{{or .State.Status .State.Restarting}}' $(docker ps -q)
# running
# running

3) 判断方式:

代码语言:javascript
复制
1)  eq: 相等,即 arg1 == arg2。比较特殊的是,它支持多个参数进行与比较,此时它会将第一个参数和其余参数依次比较,返回下式的结果:
# {{if eq true .Var1 .Var2 .Var3}}{{end}}
# 效果等同于:
# arg1==arg2 || arg1==arg3 || arg1==arg4 ...
2) ne: 不等,即 arg1 != arg2。
3) lt: 小于,即 arg1 < arg2。
4) le: 小于等于,即 arg1 <= arg2。
5) gt: 大于,即 arg1 > arg2。
6) ge: 大于等于,即 arg1 >= arg2。

基础示例:

代码语言:javascript
复制
# 示例1.输出所有非正常已停止的容器名称:
docker inspect --format '{{if ne 0 .State.ExitCode}}非正常停止的容器:{{.Name}}{{end}}' $(docker ps -aq)
# 非正常停止的容器:/unruffled_bhabha
# 非正常停止的容器:/intelligent_borg

# 示例2.判断容器是否在运行之中
docker inspect --format '{{if ne "exited" .State.Status}}{{.Name}} 运行中{{else}}{{.Name}}  已停止{{end}}' $(docker ps -aq)
# /data-volume-1  已停止
# /unruffled_bhabha  已停止
# /intelligent_borg  已停止
# /test1 运行中
# /ldap-account-manager 运行中
# /phpldapadmin  已停止
# /openldap  已停止
docker inspect --format '{{if not .State.Running}}{{.Name}}{{else if .}}该容器{{.Name}}还在运行{{end}}' $(docker ps -aq)
# /data-volume-1
# /unruffled_bhabha
# /intelligent_borg
# 该容器/test1还在运行
# 该容器/ldap-account-manager还在运行
# /phpldapadmin
# /openldap

 
# 示例3.输出所有已停止或配置了 Restarting 策略的容器名称
docker inspect --format '{{if eq "exited" .State.Status}}{{.Name}}{{else if eq .State.Restarting true}}容器{{.Name}}配置了Restarting策略.{{else}}容器{{.Name}}正在运行,但是没有配置Restarting策略{{end}}' $(docker ps -aq)
# /data-volume-1
# /unruffled_bhabha
# /intelligent_borg
# 容器/test1正在运行,但是没有配置Restarting策略
# 容器/ldap-account-manager正在运行,但是没有配置Restarting策略
# /phpldapadmin
# /openldap
6.遍历(循环)

描述:range 用于遍历结构内返回值的所有数据。支持的类型包括 array, slice, map 和 channel。使用要点:

  • 对应的值长度为 0 时 range 不会执行。
  • 结构内部如要使用外部的变量,需要在前面加引用比如Var2。
  • range 也支持 else 操作。效果是当返回值为空或长度为 0 时执行 else 内的内容。

基础语法:

代码语言:javascript
复制
{{range pipeline}}{{.}}{{end}}
{{range pipeline}}{{.}}{{else}}{{.}}{{end}}

基础示例:

代码语言:javascript
复制
# 容器健康检查时间一览
docker inspect dc1 --format='{{range .State.Health.Log}}{{.Start}}{{println}}{{end}}'
2020-07-07 16:25:51.354025918 +0800 CST
2020-07-07 16:26:51.423164721 +0800 CST
2020-07-07 16:27:51.56890628 +0800 CST
2020-07-07 16:28:51.635154369 +0800 CST
2020-07-07 16:29:51.70101931 +0800 CST

# 获取容器的IP (后面使用容器名或容器ID都可以)
docker inspect dc1 --format='{{ .NetworkSettings.Networks}}'
map[opt_default:0xc0001e2f00]
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
172.17.0.2
172.18.0.2
管道(Pipeline)

描述: 管道 即 pipeline 与 shell 中类似,可以是上下文的变量输出,也可以是函数通过管道传递的返回值。

简单示例:

代码语言:javascript
复制
示例:
{{.Con | markdown | addlinks}}  # 管道拼接的是内置函数
{{.Name | printf "%s"}}

基础示例:

代码语言:javascript
复制
# 示例1.管道参数传递
docker inspect --format '{{.State.Status}}' $(docker ps -aq)
# exited
# running
docker inspect --format '{{.State.Status | len}}' $(docker ps -aq)
# 6
# 7
内置函数
len 函数

描述:返回相应对象的长度。 示例:

代码语言:javascript
复制
docker inspect --format '{{len .Name}}' $INSTANCE_ID

0x02 扩展语法

描述:基于第三方进行增强模板及函数,例如Docker中基于go模板的基础上,构建了一些内置函数。

Docker 扩展

1.json: Docker 默认以字符串显示返回结果。而该函数可以将结果格式化为压缩后的 json 格式数据。

代码语言:javascript
复制
join
# 获取 Config 字段对应的 json 数据
docker inspect --format='{{json .Config}}' $INSTANCE_ID

2.join:用指定的字符串将返回结果连接后一起展示。操作对象必须是字符串数组。

代码语言:javascript
复制
# 输出容器配置的所有 Entrypoint 参数,以 " , " 分隔:
docker inspect --format '{{join .Config.Entrypoint " , "}}' $INSTANCE_ID

3.lower: 将返回结果中的字母全部转换为小写。操作对象必须是字符串。

4.upper: 将返回结果中的字母全部转换为大写。操作对象必须是字符串。

代码语言:javascript
复制
docker inspect --format "{{lower .Name}}" $INSTANCE_ID
docker inspect --format "{{upper .Name}}" $INSTANCE_ID

5.title: 将返回结果的首字母转换为大写。操作对象必须是字符串,而且不能是纯数字。

代码语言:javascript
复制
docker inspect --format "{{title .State.Status}}" $INSTANCE_ID

6.split: 使用指定分隔符将返回结果拆分为字符串列表。操作对象必须是字符串且不能是纯数字。同时字符串中必须包含相应的分隔符,否则会直接忽略操作。

代码语言:javascript
复制
docker inspect --format '{{split .HostsPath "/"}}' $INSTANCE_ID
# [ var lib docker containers dc1cc7e934aa756ab9f1d5aa88b6fb3b9124a101f0f1313fca199bd942d24e5b hosts]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 前言简述
  • 0x01 基础语法
    • 1.注释
      • 2.打印信息
        • 3.变量
          • 4.索引
            • 5.条件判断
              • 6.遍历(循环)
                • 管道(Pipeline)
                  • 内置函数
                    • len 函数
                • 0x02 扩展语法
                  • Docker 扩展
                  相关产品与服务
                  容器镜像服务
                  容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档