使用Perl从长列表中提取特定信息

时间:2010-05-13 21:51:32

标签: perl parsing text

我在这里使用的文件是LDAP提取的结果,但我需要最终将信息格式化为电子表格可以使用的内容。

所以,数据如下:

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: John Doe
name: ##userName

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: Jane Doe Jr
name: ##userName

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: Ted Doe
name: ##userName

我需要导出的格式为:

firstName lastName userName
firstName lastName userName
firstName lastName userName

如果空格是制表符,那么我可以将该文件导入数据库。我有在VBScript中这样做的经验,但我正在尝试切换到使用Perl进行尽可能多的服务器管理。

我不确定我想要的语法基本上是

while not endoffile{
detect "displayName: " & $firstName & " " & $lastName
detect "name: ##" & $userName

write $firstName tab $lastName tab $userName to file
}

另外,如果有人能指出我专门针对Perl使用的文本解析语法的资源,我将非常感激。我遇到的大部分资源都不是很有帮助。

此外,一些userNames是数字。前两个数字仍需要修剪,但如果有帮助,则userName总是6个字符长。

2 个答案:

答案 0 :(得分:3)

这样的东西应该做的 - 它从stdin读取并输出到stdout,所以你可以使用普通的unix管道来使用文件:

#!/usr/bin/perl

use strict;
use warnings;
use String::Util 'trim';

# set "line ending" to \n\n, to allow slurping by paragraphs:
local $/ = "\n\n";

while (my $line = <>)
{
    chomp $line;

    my ($displayName) = ($line =~ /^displayName: (.+)$/m);
    my ($name) = ($line =~ /^name: ##(.+)$/m);
    trim $displayName;
    trim $name;

    my ($firstName, $lastName) = ($displayName =~ /^([^ ]+) (.+)$/);

    print "$firstName\t$lastName\t$name\n";
}

我使用您在下面提供的示例输入测试了这个,test.pl < input.txt并得到了输出:

John    Doe     userName
Jane    Doe     userName
Ted     Doe     userName

您可以在{/ 3}}下的$ /或者此SO问题(需要链接)下阅读段落模式中的诽谤。使用匹配运算符上的m标志启用多行内匹配 - 请参阅perldoc perlvar

答案 1 :(得分:0)

这是我的解决方案。

use strict;
use warnings;
my $fh;
my $file_contents;
my @info;
open $fh, '<', "data" or die($!);
local $/ = undef;
$file_contents = <$fh>;

while($file_contents =~ /.ame: (.*?)$(.*?).ame: (.*?)$/smg)
{

   my $displayname = $1;
   my $username = $3;
   $displayname =~ s/^\s+//; #clean off any whitespace from front/back
   $displayname =~ s/\s+$//;
   my ($firstname, $lastname) = split(/\s+/, $displayname); #split on whitespace

   print "$firstname\t$lastname\t$username\n"; #note the tabs
}