我希望在Perl中迭代一个文件,如果找到一个特定的单词,那么将其他行存储在符合特定模式的行之后。 ldap.txt文件在几个Gigs中相当大。
test1
game
dn: uid=test1,ou=people,dc=admin,dc=local
blah
blah
maillocaladdress: test1@example.com
maillocaladdress: test.team@example.com
maillocaladdress: test11@example.com
some date
some more data
data
dn: uid=game,ou=people,dc=admin,dc=local
blah
blah
maillocaladdress: game@example.com
maillocaladdress: game.test@example.com
maillocaladdress: game-test@example.com
some date
some more data
data
依旧......
打开user.txt并遍历每个用户并检查dn:line中ldap.txt上的每一行。如果匹配,则将匹配maillocaladdress的所有行的值存储到varialbe,我假设在散列键/值pari中,但这里的值大于1。
e.g。
test1 matches dn: uid=test1,ou=people,dc=admin,dc=local
为每个用户存储以下值。
test1@example.com
test.team@example.com
test11@example.com
码
#! /usr/bin/perl
use strict;
use warnings;
my $ldiffile = shift;
my %emails;
open my $US, '<', 'users2.txt'
or die "Could not Open the file users2.txt: $!";
open my $FH, '<', $ldiffile
or die "Could not Open the file $ldiffile: $!";
chomp(my @users = <$US>);
#print "@users \n";
foreach my $uid (@users) {
print "$uid \n";
# while ( chomp(my $line = <$FH>) ) {
while (my $line = <$FH>) {
chomp ($line);
if ( $line =~ /dn: uid=$uid,ou=People,dc=admin,dc=local/i ) {
print "$line \n";
if ( $line =~ /mailLocalAddress: ([\w\.\-\_\@]+)/ ) {
print "<<<< $line >>>> \n";
push ( @{$emails{$uid}}, $1 );
}
}
}
}
答案 0 :(得分:1)
哈希用户列表。然后,迭代第二个文件。记住您当前正在解析的用户($ user)。如果您看到电子邮件地址,请将其存储。
#!/usr/bin/perl
use warnings;
use strict;
my %users;
open my $USER, '<', 'user.txt' or die $!;
while (<$USER>) {
s/\s*$//; #/ Sample input contains trailing whitespace.
undef $users{$_};
}
my $user = q();
open my $LDAP, '<', 'ldap.txt' or die $!;
while (<$LDAP>) {
s/\s*$//;
$user = $1 if /dn: uid=(.*?),ou=people,dc=admin,dc=local/;
push @{ $users{$user} }, $1 if exists $users{$user}
and /maillocaladdress: (.*)/;
}
for my $user (keys %users) {
print "$user\n\t";
print join "\n\t", @{ $users{$user} };
print "\n";
}
答案 1 :(得分:0)
你的程序中可能存在一些缺陷。您试图为每个@users迭代文件,但是您只是为第一个用户循环遍历该文件。
您应该做的只是循环遍历文件并提取用户ID并将其与您接受的用户列表进行匹配。以下应该做你想要的:
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
open my $US, '<', 'users2.txt';
chomp(my @users = <$US>);
close $US;
my %isuser = map {$_ => 1} @users;
my %emails;
my $userid = '';
while (<>) {
chomp;
if (/^dn: uid=([^,]*)/) {
$userid = $1;
$userid = '' if !/,ou=People,dc=admin,dc=local/;
} elsif ($isuser{$userid}) {
if (/mailLocalAddress: ([\w.-_@]+)/i) {
print "$userid - <<<< $_ >>>> \n";
push @{$emails{$userid}}, $1;
}
}
}
另外,测试mailLocalAddress的正则表达式是大写字母,而示例数据则没有。因此在正则表达式上放置/i
标志。