Позвольте мне начать с того, что описание вашей проблемы не очень полезно. В следующий раз, пожалуйста, будьте более конкретны: Вы можете упустить гораздо лучшие решения.
Итак, из вашего описания я понимаю, что у вас есть два файла, которые содержат разделенные пробелами данные. В первом файле вы хотите сопоставить первые три столбца с некоторым шаблоном поиска. Если найдено, вы хотите найти все строки в другом файле, которые содержат четвертый и пятый столбец соответствующей строки в первом файле. Из этих строк необходимо извлечь второй и третий столбец, а затем распечатать первый столбец первого файла, а второй и третий - из второго файла. Хорошо, здесь идет:
#!/usr/bin/env perl -nwa
use strict;
use File::Find 'find';
my @search = qw(X Y Z);
# if you know in advance that the otherfile isn't
# huge, you can cache it in memory as an optimization.
# with any more columns, you want a loop here:
if ($F[0] eq $search[0]
and $F[1] eq $search[1]
and $F[2] eq $search[2])
{
my @files;
find(sub {
return if not -f $_;
# verbatim search for the columns in the file name.
# I'm still not sure what your file-search criteria are, though.
push @files, $File::Find::name if /\Q$F[3]\E/ and /\Q$F[4]\E/;
# alternatively search for the combination:
#push @files, $File::Find::name if /\Q$F[3]\E.*\Q$F[4]\E/;
# or search *all* files in the search path?
#push @files, $File::Find::name;
}, '/search/path'
)
foreach my $file (@files) {
open my $fh, '<', $file or die "Can't open file '$file': $!";
while (defined($_ = <$fh>)) {
chomp;
# order of fields doesn't matter per your requirement.
my @cols = split ' ', $_;
my %seen = map {($_=>1)} @cols;
if ($seen{$F[3]} and $seen{$F[4]}) {
print join(' ', $F[0], @cols[1,2]), "\n";
}
}
close $fh;
}
} # end if matching line
В отличие от решения другого автора, которое содержит множество системных вызовов, оно вовсе не относится к оболочке и поэтому должно быть достаточно быстрым.