Reputation: 17
I was looking for the best way to parse some text results which appear on multiple line.
The results are coming from ldapSearch and are presented in such a way:
sn: 1234
name: frank
mail: [email protected]
phone: 123 456 7890
sn: 2345
name: john
mail: [email protected]
phone: 123 456 7890
Although this can easily be done by putting all lines in an @array
and then using split to get the actual value, my problem is that depending on the specific record, some lines might be omitted when dont contain any value.
So some records might show up as:
sn: 3456
name: mary
phone: 234 567 8901 (missing mail attribute)
So in this case, blindly reading for the position number won't help. Any idea of a way to actually search for the line name and then read the result?
Many thanks, Frank
Upvotes: 0
Views: 250
Reputation: 6578
This might achieve what you're after:
#!/usr/bin/perl -w
use strict;
my $infile = 'in.txt';
open my $input, '<', $infile or die "Can't open to $infile: $!";
Input:
sn: 1234
name: frank
mail: [email protected]
phone: 123 456 7890
sn: 2345
name: john
mail: [email protected]
phone: 123 456 7890
name: bob # This entry has only a name and number
phone: 44 4232 232
-
while (<$input>){
chomp;
my ($sn) = /sn: (\d+)/;
print "Sn: $sn\n" if $sn;
my ($name) = /name: (\w+)/;
print "Name: $name\n" if $name;
my ($email) = /mail: (.+\@.+)/;
print "Email: $email\n" if $email;
my ($phone) = /phone: (.*)/;
print "Phone: $phone\n" if $phone;
# do something with the variables...
}
Outputs:
Sn: 1234
Name: frank
Email: [email protected]
Phone: 123 456 7890
Sn: 2345
Name: john
Email: [email protected]
Phone: 123 456 7890
Name: bob
Phone: 44 4232 232
Upvotes: 0
Reputation: 3460
I would iterate over the lines, looking for an indication that the current entity has changed:
#!/usr/bin/perl -w
use strict;
use warnings;
my %records;
my $sn = 'unknown';
while (my $line = <>) {
chomp $line;
next unless $line;
my ($key,$value) = $line =~ m/^(\w+):\s*(.*)/;
if ($key eq 'sn') {
$sn = $value;
}
$records{$sn}->{$key} = $value;
}
use Data::Dumper;
print Dumper( \%records );
Upvotes: 0
Reputation: 50637
You can read all attributes into hash,
chomp(@array);
my %user = map { split /\s*:\s*/, $_, 2 } @array;
# print $user{name}, $user{phone}
Upvotes: 1