从perl数组中提取特定数据标记

时间:2010-11-16 21:48:06

标签: perl vmware

我正在尝试从perl数组中提取特定数据标记。这几乎是我之前关于从命令输出构建数组的问题的扩展。

我尝试使用用户给我的表达式。有用!但它使用固定长度的字段,并经过一些研究,找出这意味着什么,我发现它不适合我。

无论如何都要使用相同的表达式并删除固定长度的字段。

以下是我从last question获得的代码。

foreach ( @line ) { 
# this is the get-it-and-do-something-else-with-it version
my ( $vmid, $name, $file )
    = substr( $_, 0, 47 ) =~ m/^ ( \d+ ) \s+ ( \S+ ) \s+ (.*\S) \s* $/x
    ;

最好的结果是能够将各种比赛与$ 1,$ 2,$ 3等联系起来。

2 个答案:

答案 0 :(得分:1)

我提供了答案,取决于格式是固定长度的想法。如果这不起作用那么,为了理智,我们需要做出另一个假设。这个顺序是前两个捕获正常,但第三个不能使用,因为它取决于固定长度格式。

无空格文件名假设

所以新假设是以下顺序:

  • 一个'['字符
  • 后跟任意数量的非'['字符
  • 后跟关闭']'字符
  • 后面是空白
  • 后跟非空白字符
  • 指定的文件

然后这应该有效:

my ( $vmid, $name, $file )
    = m/^ ( \d+ ) \s+ ( \S+ ) \s+ ( [[] [^\]]+ [\]] \s+ \S+) /x
    ;

'Nix Filenames

但我最初没有提出这个问题的原因是* NIX文件可以包含空格,并且列看起来包含固定宽度的假设。因此,我试图通过对数据的简单实用假设来避免一些未知的复杂性。

这是文件名中的单个空格,由输出中的多个空格区分。我将在下面显示,但如果数据在文件名和空格中使用空格来分隔列 AND 允许在Guest OS,Version或Annotation字段中使用空格。然后你不会得到你想要的正则表达式。

仅限单一空间的假设

这是单空间假设:

m/^ ( \d+ ) \s+ ( \S+ ) \s+ ( \[ [^\]]+ \] \s+ \S+ (?: [ ] \S+ )* )  /x

Ye-argh !! 或蛮力方法

以下(更多)特例代码可以涵盖更难的案例:

my ( $vmid, $name, $file_haystack )
    = m/^ ( \d+ ) \s+ ( \S+ ) \s+ (.*\S) \s* $/x
    ;
my @file_parts = split ' ', $file_haystack;
my $file_name  = shift @file_parts; 
while ( @file_parts and !-d $file_name ) { 
    $file_name .= ' ' . shift @file_parts;
}

但是 假定 存在文件正在您正在读取输出的系统上。如果不是这种情况,您可以进行dot-vmx假设:

m/^ ( \d+ ) \s+ ( \S+ ) \s+ ( \[ [^\]]+ \] \s+ .* [.]vmx ) \s /x

这一切可能都没有实际意义 OR 你比我更接近数据

当然这可能都没有实际意义,因为也许你可以将命令传递给你的脚本,使列明确无误,比如CVS格式。或者,如果它打印一个包含空格的路径,它将在它周围打印双引号。 OR 也许您可以在路径名中显示空格,并在它们前面加上 escapes

双引号假设:
m/^ ( \d+ ) \s+ ( \S+ ) \s+ ( \[ [^\]]+ \] \s+ (?:" [^"]+ " | \S+ ))/x
Excaped space假设:
m/^ ( \d+ ) \s+ ( \S+ ) \s+ ( \[ [^\]]+ \] \s+ (?: [^\s\\]+ | (\\\\)*\\. )/x

如果报告程序没有在输出中放置规则 - 或者如果你的内部流程没有规定它缺乏规则,那么就不能做出万无一失的假设。

答案 1 :(得分:0)

略微混淆,因此您将有动力学习基本语言功能:

#!/usr/bin/perl

use strict; use warnings;
use YAML;

my @data;

m{^
  (?<vmid> \d+)
  [ ]+
  (?<name> \w+)
  \s+
  (?<file> \[\w+\][ ]\S+)
  \s+
  (?<os> \w+)
  \s+
  (?<version> \S+)
}x and push @data, { %+ } while <DATA>;

print Dump \@data;

__DATA__
Vmid   Name                File                 Guest OS      Version   Annotation
128    NS01    [datastore2] NS01/NS01.vmx     ubuntu64Guest   vmx-07
144    NS02    [datastore2] NS02/NS02.vmx     ubuntu64Guest   vmx-07
208    MX01    [datastore2] MX01/MX01.vmx     ubuntu64Guest   vmx-07
224    SQL01   [datastore2] SQL01/SQL01.vmx   ubuntu64Guest   vmx-07
240    WS01    [datastore2] WS01/WS01.vmx     ubuntu64Guest   vmx-07