A ferramenta que você precisa para isso são os hashes - que são o modo de armazenar os pares de valores-chave do perl. Especificamente - precisamos pré-processar seus dados em um hash, para que possamos "procurar" lugares onde os valores mais baixos ou XXX
estejam presentes.
Felizmente - sua terceira condição parece um subconjunto do seu segundo - se você está apenas imprimindo o valor mais baixo, o menor valor quando há apenas um, é o mesmo.
Então eu provavelmente faria algo assim:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
#read header line, because we don't want to process it;
#note - diamond operators are 'magic' file handles.
#they read either piped input on STDIN, or
#open/read files specified on command line.
#this is almost exactly like how sed/grep work.
my $header_line = <>;
#turn the rest of our intput into an array of arrays, split on whitespace/linefeeds.
my @lines = map { [split] } <>;
#print for diag
print Dumper \@lines;
#this hash tracks if we've 'seen' an XXX
my %skip_type;
#this hash tracks the lowest V2 value.
my %lowest_v2_for;
foreach my $record (@lines) {
#we could work with $record ->[0], etc.
#this is because I think it's more readable this way.
my ( $type, $v1, $v2 ) = @$record;
#find all the lines with "XXX" - store in a hash.
if ( $v1 eq "XXX" ) {
$skip_type{$type}++;
}
#check if this v2 is the lowest for this particular type.
#make a note if it is.
if ( not defined $lowest_v2_for{$type}
or $lowest_v2_for{$type} > $v2 )
{
$lowest_v2_for{$type} = $v2;
}
}
#print for diag - things we are skipping.
print Dumper \%skip_type;
print $header_line;
#run through our list again, testing the various conditions:
foreach my $record (@lines) {
my ( $type, $v1, $v2 ) = @$record;
#skip if it's got an XXX.
next if $skip_type{$type};
#skip if it isn't the lowest value
next if $lowest_v2_for{$type} < $v2;
#print otherwise.
print join( " ", @$record ), "\n";
}
Isto dá (menos alguma saída de diagnóstico de Dumper
que pode ser descartada livremente se você não quiser):
Name v1 v2
Type4 ABC 55
Type5 ABC 99
Type6 DEF 00