使用Perl的段落模式拆分它们之间有额外空格的段落

时间:2013-07-26 21:41:44

标签: perl whitespace paragraph backticks

我正在尝试解析pvdisplay(8)的输出,为每个物理卷打印一个单独的“段落”:

  --- Physical volume ---
  PV Name               /dev/sdb
  VG Name               vg_virtual_01
  PV Size               16.37 TiB / not usable 2.25 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              4291533
  Free PE               3830989
  Allocated PE          460544
  PV UUID               zqi1Q6-tIag-ghQy-MmdJ-kyOS-XkmY-HpyQ51

  --- Physical volume ---
  PV Name               /dev/sda
  VG Name               vg_virtual_02
  PV Size               16.37 TiB / not usable 2.25 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              4291533
  Free PE               1525709
  Allocated PE          2765824
  PV UUID               BlYvJW-ieVx-AjRg-p3r6-e4oC-TkPc-u2lf7x

很简单,对吧?

#!/usr/bin/perl

use strict;
use warnings;

my @pvs = do {
    local $/ = '';
    `pvdisplay`;
};

事实证明,并不像我想象的那么简单。经过半个小时的抨击键盘因为我的数组只得到一个项目,我意识到段落之间的空行实际上在EOL之前包含额外的空格。根据perlvar,如果设置为空字符串,$/将空行视为终止符,并注意空行不能包含任何空格或制表符。当然,$/是一个字符串,而不是正则表达式,因此我无法将其设置为/^\s+$/

我能看到的唯一方法是首先将输出保存到文件中,去除无关的空白,然后再读回来,但我不想为这么简单的事情创建一个临时文件。有更优雅的方式吗?

编辑:我可以使用split(/ ^ \ s + $ / m)执行此操作,但我只是好奇是否可以通过更改$ / 来实现此目的

2 个答案:

答案 0 :(得分:2)

咦?只需自己拆分输出:

my @pvs = split /\n\s*\n/, scalar `pvdisplay`;

不,除非确切的分隔符是字符的已知字符,否则无法使用$/(如果有两个空格,则可以尝试$/ = "\n \n")。不要试图不必要地让你的工作更难。

答案 1 :(得分:1)

#!/usr/bin/env perl

use strict;
use warnings;

local $/ = '--- Physical volume ---';

while (my $chunk = <DATA>) {
    chomp $chunk;
    $chunk =~ s/\A \s+ //x;
    $chunk =~ s/\s+ \z //x;
    next unless $chunk =~ /\S/;
    my %obs = ($chunk =~  /^ (.+?[eED]) \s{2,} (\S .+)  $/gxm);
    use YAML;
    print Dump \%obs;
}



__DATA__
--- Physical volume ---
PV Name               /dev/sdb
VG Name               vg_virtual_01
PV Size               16.37 TiB / not usable 2.25 MiB
Allocatable           yes
PE Size               4.00 MiB
Total PE              4291533
Free PE               3830989
Allocated PE          460544
PV UUID               zqi1Q6-tIag-ghQy-MmdJ-kyOS-XkmY-HpyQ51

--- Physical volume ---
PV Name               /dev/sda
VG Name               vg_virtual_02
PV Size               16.37 TiB / not usable 2.25 MiB
Allocatable           yes
PE Size               4.00 MiB
Total PE              4291533
Free PE               1525709
Allocated PE          2765824
PV UUID               BlYvJW-ieVx-AjRg-p3r6-e4oC-TkPc-u2lf7x

输出:

$ ./gg.pl
---
Allocatable: yes
Allocated PE: 460544
Free PE: 3830989
PE Size: 4.00 MiB
PV Name: /dev/sdb
PV Size: 16.37 TiB / not usable 2.25 MiB
PV UUID: zqi1Q6-tIag-ghQy-MmdJ-kyOS-XkmY-HpyQ51
Total PE: 4291533
VG Name: vg_virtual_01
---
Allocatable: yes
Allocated PE: 2765824
Free PE: 1525709
PE Size: 4.00 MiB
PV Name: /dev/sda
PV Size: 16.37 TiB / not usable 2.25 MiB
PV UUID: BlYvJW-ieVx-AjRg-p3r6-e4oC-TkPc-u2lf7x
Total PE: 4291533
VG Name: vg_virtual_02