grep between pattern 并在输出中排除 start/end 模式

grep between pattern and exclude start/end pattern in output

我有 file.txt,我需要从中 grep 第一次出现的模式。如何 grep 并仅获取匹配的字符串 ':whitespace' 和 'end of line' 我正在尝试以下命令

cat file.txt |  grep -m1 -P "(:\s+).*ccas-apache$"

但它给了我

name: nginx-ccas-apache

而我想要的是

nginx-ccas-apache

file.txt

pod: nginx-ccas-apache-0
        name: nginx-ccas-apache
        image: myregnapq//ccas_apache
        name: nginx-filebeat
pod: nginx-ccas-apache-1
        name: nginx-ccas-apache
        image: myregnapq/ccas_apache
        name: nginx-filebeat

使用grep

$ grep -Pom1 'name: \K.*$' file.txt
nginx-ccas-apache

你也可以使用awk:

awk -F: '/:[[:space:]].*ccas-apache$/{sub(/^[[:space:]]+/, "", ); print ; exit}'  file

详情:

  • -F: - 冒号用作字段分隔符
  • :[[:space:]].*ccas-apache$ - 搜索带有 : 的行,一个空格,然后是任何文本,ccas-apache 在字符串的末尾,一旦找到
  • sub(/^[[:space:]]+/, "", ) - 从字段 2
  • 中删除初始空格
  • print - 然后打印字段 2 值
  • exit - 停止处理文件。

参见 online demo:

#!/bin/bash
s='pod: nginx-ccas-apache-0
        name: nginx-ccas-apache
        image: myregnapq//ccas_apache
        name: nginx-filebeat
pod: nginx-ccas-apache-1
        name: nginx-ccas-apache
        image: myregnapq/ccas_apache
        name: nginx-filebeat'

awk -F: '/:[[:space:]].*ccas-apache$/{sub(/^[[:space:]]+/, "", ); print ; exit}' <<< "$s"

输出:nginx-ccas-apache

另一种使用sed的方法:

sed -En '/^[[:space:]]+name:[[:space:]](.*ccas-apache)$/{s///p;q}' file.txt

说明

  • -En 将扩展正则表达式与 -E 结合使用,并防止 sed 通过 -n

    默认打印一行
  • /^[[:space:]]+name:[[:space:]](.*ccas-apache)$/ 指定匹配内容的模式

  • 如果前面的模式匹配,运行 大括号之间的命令

  • s///p 将最后匹配的模式与 // 一起使用并替换为第 1 组。然后将模式 space 打印为 p

  • q 退出 sed

正则表达式匹配:

  • ^ 字符串开头
  • [[:space:]]+name:[[:space:]]name: 与前导 space 和
  • 之后的单个 space 匹配
  • (.*ccas-apache) 捕获组 1,匹配可选字符和 ccas-apache
  • $ 字符串结束

输出

nginx-ccas-apache

请注意,您不必使用 cat

看到 online demo.

输入

pod: nginx-ccas-apache-0
        name: nginx-ccas-apache
        image: myregnapq//ccas_apache
        name: nginx-filebeat
pod: nginx-ccas-apache-1
        name: nginx-ccas-apache
        image: myregnapq/ccas_apache
        name: nginx-filebeat

代码

  • __输入任何properly-escaped模式,包括字符串tail$

    • 3 种表达同一事物的方式
    • 任何一种解决方案都适用于gawkmawk-1mawk-2macos nawk
mawk '_{exit} _=$(NF=NF)~__' FS='^.*[ \t]' __='ccas-apache$' OFS=
or
gawk '_{exit} NF*=_=$(NF)~__' FS='^.*[ \t]' __='ccas-apache$' OFS=
or
nawk '_{exit} _=NF*=$NF~__' FS='^.*[ \t]' __='ccas-apache$' OFS=

输出

nginx-ccas-apache

通用解决方案

  • 不只是在尾部
  • 这次输入模式在 FS

代码

{m,g}awk '_{exit} _=(!_<NF)*sub("[^ \t]*"(FS)"[^ \t]*","&")*\
                    gsub("^[^]*|[^]*$","")' FS='your_pattern_here'

输出

FS='image' 

    >>> `image:`

FS='myregnapq'

    >>> `myregnapq//ccas_apache`

使用您显示的示例,请尝试以下 awk 代码。

awk -F':[[:space:]]+' '
~/^[[:space:]]+name$/ && ~/^[^-]*-ccas-apache$/{
  print 
  exit
}
' Input_file

解释: 简单的解释就是,将字段分隔符设置为冒号后跟 space(出现 1 次或多次) .在主程序检查条件中,如果第一个字段匹配正则表达式以 space 开头,然后是名称,并且第二个字段匹配正则表达式 ^[^-]*-ccas-apache$ 然后打印该行的第二个字段并从程序中退出。