【问题标题】:extract text between the two blocks using regex使用正则表达式提取两个块之间的文本
【发布时间】:2022-06-10 18:30:18
【问题描述】:

我正在尝试使用以下正则表达式提取两个字符串之间的文本。

(?s)Non-terminated Pods:.*?in total.\R(.*)(?=Allocated resources)

此正则表达式在 regex101 中看起来不错,但在与 perlgrep -P 一起使用时,不知何故不打印 pod 详细信息。下面的命令导致空输出。

kubectl describe  node |perl -le '/(?s)Non-terminated Pods:.*?in total.\R(.*)(?=Allocated resources)/m; printf "$1"'

这里是示例输入:

PodCIDRs:                     10.233.65.0/24
Non-terminated Pods:          (7 in total)
  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
Allocated resources:

问题

  1. 如何从上述输出中提取信息,如下所示。我正在使用的正则表达式或命令有什么问题?
Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)  

问题-2:如果我有两个相似的输入块怎么办。如何提取 pod 详细信息? 例如:

如果输入是:

PodCIDRs:                     10.233.65.0/24
Non-terminated Pods:          (7 in total)
  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
Allocated resources:
....some
.......random data...
PodCIDRs:                     10.233.65.0/24
Non-terminated Pods:          (7 in total)
  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo-1                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-2                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp3-2                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
Allocated resources:

【问题讨论】:

  • 请只问一个问题。
  • 1) “与 perl 一起使用”如何(准确地说)? 2)所以你想从一个可能有很多块的文件中提取所有这些块,对吧? 3) Allocated resources: 短语(行?)always 是否在感兴趣的块之后的行上,即使是文件中最后一个这样的“Pod”?

标签: regex perl grep


【解决方案1】:

使用gnu-grep,您可以通过一些调整来使用您的正则表达式:

kubectl describe  node |
grep -zoP '(?s)Non-terminated Pods:.*?in total.\R\K(.*?)(?=Allocated resources)'

  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
  • \R 之后使用\K(匹配重置)从输出中删除该行
  • 使用-z 选项将输入和输出数据视为行序列,每行以零字节(ASCII NUL 字符)而不是换行符结尾。

PS:相同的正则表达式也适用于第二个输入块以及每个块之前显示的标题行。


或者您也可以使用任何版本的sed 来完成这项工作:

kubectl describe  node |
sed -n '/Non-terminated Pods:.*in total.*/,/Allocated resources:/ {//!p;}'

  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
  kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
  kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s

【讨论】:

    【解决方案2】:

    有一些明显的假设,并保持接近问题中的模式:

    perl -0777 -wnE'
        @pods = /Non-terminated\s+Pods:\s+\([0-9]+\s+in\s+total\)\n(.*?)\nAllocated resources:/gs;
        say for @pods
    ' input-file
    

    (注意这条宽行中正则表达式的修饰符:/gs


    问题并没有说明正则表达式“perl一起使用”的精确程度;我不能说是什么失败了。

    问题中的正则表达式在单个文本块上使用而不是此答案中的正则表达式(并且没有 /s 修饰符,因为它应该)时有效。要使用多个这样的块,它们之间还有其他文本,其中的(.*) 需要更改为(.*?)

    对上述命令行程序的评论:

    • -0777switch 使其将整个文件读入一个字符串,在程序中的变量$_ 中可用,其正则表达式默认为bound

      还有开关-g-0777的别名,可用starting with 5.36.0

    • 我们仍然需要-n 开关,以便程序遍历输入的“行”(STDIN 或文件)。在这种情况下,input record separator 未定义,因此只有一个“行”

    • 正则表达式捕获are returned,因为匹配运算符在列表上下文中,被分配给数组@pods

    【讨论】:

      【解决方案3】:

      使用您展示的示例,请尝试遵循 GNU awk 代码。用 GNU awk 编写和测试。简单的解释是,将 Input_file 的 RS 设置为 Non-terminated Pods:.*Allocated resources:。然后在主程序中检查RT 是否不为空,然后使用awkgsub 函数将(^|\n)Non-terminated Pods:[^\n]*\n\nAllocated resources:\n* 替换为RT 变量中的NULL,然后打印其值,这将提供如图所示的输出样本。

      awk -v RS='Non-terminated Pods:.*Allocated resources:' '
      RT{
        gsub(/(^|\n)Non-terminated Pods:[^\n]*\n|\nAllocated resources:\n*/,"",RT)
        print RT
      }
      '  Input_file
      

      【讨论】:

        【解决方案4】:

        一个可能的解决方案可能是一个非常大的文件逐行读取。

        选择感兴趣的行范围并删除最后一个未包含在所需输出中的行。

        use strict;
        use warnings;
        
        while(<>) {
            if( /^  Namespace/ .. /^Allocated resources:/ ) {
                print unless /^Allocated resources:/;
            }
        }
        
        exit 0;
        

        输出

          Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
          ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
          default                     foo                                         0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
          kube-system                 nginx-proxy-kube-worker-1                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
          kube-system                 nodelocaldns-xbjp8                          100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
          Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
          ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
          default                     foo-1                                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         105s
          kube-system                 nginx-proxy-kube-worker-2                   25m (1%)      0 (0%)      32M (1%)         0 (0%)         9m8s
          kube-system                 nodelocaldns-xbjp3-2                        100m (5%)     0 (0%)      70Mi (4%)        170Mi (10%)    7m4s
        andreyv@yahoo:~/work/perl$ vi range.pl
        

        【讨论】:

          猜你喜欢
          • 2015-05-17
          • 2014-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-11
          • 1970-01-01
          • 2017-06-16
          相关资源
          最近更新 更多