Program: Sorting Your Mail
The program in Example 10.1 sorts a mailbox by subject by reading input a
paragraph at a time, looking for one with a "From"
at the start of a line. When it finds one, it searches for the
subject, strips it of any "Re:
" marks, and stores its lowercased version in the
@sub array. Meanwhile, the messages themselves are
stored in a corresponding @msgs array. The
$msgno variable keeps track of the message number.
Example 10-1. bysub1
#!/usr/bin/perl
# bysub1 - simple sort by subject
my(@msgs, @sub);
my $msgno = -1;
$/ = ''; # paragraph reads
while (<>) {
if (/^From/m) {
/^Subject:\s*(?:Re:\s*)*(.*)/mi;
$sub[++$msgno] = lc($1) || '';
}
$msgs[$msgno] .= $_;
}
for my $i (sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msgs)) {
print $msgs[$i];
}That sort is only sorting array indices. If the
subjects are the same, cmp returns 0, so the
second part of the || is taken, which compares the
message numbers in the order they originally appeared.
If sort were fed a list like
(0,1,2,3), that list would get sorted into a
different permutation, perhaps (2,1,3,0). We
iterate across them with a for loop to print out
each message.
Example 10.2 shows how an awk
programmer might code this program, using the -00 switch to read paragraphs instead of
lines.
Example 10-2. bysub2
#!/usr/bin/perl -n00
# bysub2 - awkish sort-by-subject BEGIN { $msgno = -1 } $sub[++$msgno] = (/^Subject:\s*(?:Re:\s*)*(.*)/mi)[0] if /^From/m; $msg[$msgno] .= $_; END { print @msg[ sort { $sub[$a] ...Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access