使用正则表达式提取两个块之间的文本

mon*_*onk 4 regex perl grep

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

(?s)Non-terminated Pods:.*?in total.\R(.*)(?=Allocated resources)
Run Code Online (Sandbox Code Playgroud)

perl这个正则表达式在 regex101 中看起来很好,但在与或 一起使用时不知何故不会打印 pod 详细信息grep -P。以下命令会产生空输出。

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

这是示例输入:

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:
Run Code Online (Sandbox Code Playgroud)

问题

  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%)  
Run Code Online (Sandbox Code Playgroud)

问题-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:
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 5

有了一些明显的假设,并使其接近问题中的模式:

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

(注意此行中正则表达式的修饰符,该行太宽,无法在屏幕上显示/gs:)


/s问题中的正则表达式在单个文本块上使用而不是此答案中的正则表达式(并且没有修饰符,因为它应该)时有效。要使用多个块,(.*)需要将其更改为(.*?),以便它不会一直匹配到最后一个Allocated...

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

对上面命令行程序的注释:

  • -0777 开关使其将整个文件读入字符串,该字符串可在程序中的变量$_中使用,默认情况下正则表达式绑定到该变量

    还有 switch -g,它的别名,从 5.36.0 开始-0777可用

  • 我们仍然需要-n开关,以便程序迭代输入(STDIN或文件)的“行”。在这种情况下,输入记录分隔符未定义,因此它只是一个“行”

  • 由于匹配运算符位于列表上下文中并被分配给数组,因此返回正则表达式捕获@pods