1

我正在尝试解析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) 来做到这一点,但我只是好奇是否有办法通过更改 $/ 来做到这一点

4

2 回答 2

2

嗯?只需自己拆分输出:

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

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

于 2013-07-26T21:50:25.807 回答
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
---
可分配:是
分配的PE:460544
免费PE:3830989
PE 大小:4.00 MiB
PV 名称:/dev/sdb
PV 大小:16.37 TiB / 不可用 2.25 MiB
PV UUID:zqi1Q6-tIag-ghQy-MmdJ-kyOS-XkmY-HpyQ51
总PE:4291533
虚拟机名称:vg_virtual_01
---
可分配:是
分配PE:2765824
免费PE:1525709
PE 大小:4.00 MiB
PV 名称:/dev/sda
PV 大小:16.37 TiB / 不可用 2.25 MiB
PV UUID:BlYvJW-ieVx-AjRg-p3r6-e4oC-TkPc-u2lf7x
总PE:4291533
虚拟机名称:vg_virtual_02
于 2013-07-26T22:02:53.153 回答