grep 跨行搜索(匹配)

    grep 非常强大,可以在文件中搜索任意的字符串,通常的场景多是以行为单位进行检索,但若标识字符串与搜索内容不在一行怎么办? 例如下面的一个kubernetes部署文件,现在需要从该文件中取出部署名,也就是

 

metadata:
  name: projecta-web-ms-deployment

中的name值。

apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: projecta-web-ms-deployment
  namespace: projecta-dev
  labels:
    app: projecta-web-ms
spec:
  replicas: 1
  selector:
    matchLabels:
      app: projecta-web-ms
  template:
    metadata:
      labels:
        app: projecta-web-ms
    spec:
      nodeSelector:
        disktype: projectkdev
      containers:
        - name: projecta-web-ms
          image: 192.168.1.8/projecta.io/projecta-web:1.5.0-SNAPSHOT
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          volumeMounts:
            - name: v2
              mountPath: /usr/projecta/logs
      volumes:
        - name: v2
          hostPath:
            path: /home/docker/data/tomcat/bpm/ms/logs

(1)首先取出带标识串的部分:

因为有多个name特征串,不能使用单行搜索,否则会返回多条数据。

命令: grep -Pzo "metadata:\s*\n  name:.*$" deployment.yaml

说明:-P, --perl-regexp,使用Perl正则表达式; z,处理多行; o,只输出匹配部分。因为如果进行多行匹配,就没有换行作为匹配结束边界,会返回剩下的全部文本

结果:

metadata:
  name: projecta-web-ms-deployment

(2)提取标识符所在行

命令:grep -Pzo "metadata:\s*\n  name:.*$" deployment.yaml  | grep name

结果:

  name: pi6000-bpm-web-ms-deployment

(3)使用sed命令提取值

命令:grep -Pzo "metadata:\s*\n  name:.*$" deployment.yaml  | grep name | awk '{print $2}'

结果:

pi6000-bpm-web-ms-deployment

至此,就实现了我们最初的目标,提取出了跨行文本中的特征值。

(4)综合使用

若在脚本里执行,则需要将上述执行过程获得的值传到下面的脚本继续执行,这时,只需要定义一个变量保存提取值就可以了:

命令:

deploymentname=`grep -Pzo "metadata:\s*\n  name:.*$" deployment.yaml | grep name | awk '{print $2}'`

 

posted @ 2019-11-27 16:57  hongweigg  阅读(268)  评论(0编辑  收藏  举报