#!/usr/bin/perl use strict; use warnings; use Text::Glob 'match_glob'; # let's make up some dummy subroutines my @actions; for my $act ( 1 .. 7 ) { my $msg = " is handled by action$act\n"; $actions[$act] = sub { print $_[0], $msg }; } my %rule = ( '*' => 1, '*.txt' => 2, '*.tx?' => 7, 'fred/*' => 3, 'fred/*.mac' => 4, 'george.txt' => 5, 'fred/george.txt' => 6, ); my %rankings; for ( keys %rule ) { my $rank = length() * 100 - ( tr/*// ) * 10 - ( tr/?// ); push @{$rankings{$rank}}, $_; } my @rank_order = sort {$b<=>$a} keys %rankings; while () { chomp; my $matched; for my $rank ( @rank_order ) { for my $glob ( @{$rankings{$rank}} ) { if ( match_glob( $glob, $_ )) { $matched = $rule{$glob}; last; } } last if $matched; } if ( $matched ) { $actions[$matched]->( $_ ); } } __DATA__ foo.bar foo.bar.txt foo.bar.txo fred/foo.bar fred/foo.bar.mac george.txt fred/george.txt