in reply to Tagging the last elements

You won't be able to determine the intended output until you have read the entire input file into memory and have gone over all the records to check the numeric values associated with names in the fourth field. Maybe something like this:
#!/usr/bin/perl use strict; use warnings; my @records; my %max; while (<DATA>) { my @fields = split; my ( $number, $name ) = ( $fields[3] =~ /^(\d+),(\w+)/ ); if ( ! $number or ! $name ) { warn "Line $.: unexpected input ignored: $_"; next; } $max{$name} = $number unless ( exists( $max{$name} ) and $max{$name} >= $number ); push @records, { name => $name, data => $_ }; } for my $rec ( @records ) { my $name = $rec->{name}; my $max = $max{$name}; my $flag = ( $max == 1 ) ? 'single' : 'end'; $rec->{data} =~ s/(\s)$max,$name,/$1$flag,$name,/; print $rec->{data}; } __DATA__ 62556 63635 y 1,andrew,JJ113954 63868 63897 h 1,morgan,JJ113955 68766 69005 j 2,morgan,JJ113955 81099 81630 y 1,flintoff,JJ113952 126185 126699 s 1,austin,JJ113956 135356 135449 3 1,peter,JJ113952 135588 136297 8 2,peter,JJ113952 158146 158367 i 3,peter,JJ113952 441474 441538 b 9,catherine,JJ029490 442666 442843 9 8,catherine,JJ029490 445778 445905 0 7,catherine,JJ029490 446059 446273 l 6,catherine,JJ029490 450319 450379 f 5,catherine,JJ029490

(updated to add a condition for skipping lines that don't match /\d+,\w+/ in fourth field-- it pays to be careful...)

In the for loop, the $rec->{data} =~ s/.../.../ will do nothing on the lines that don't contain the max value for a given name, because the regex won't match. For lines that contain a max value, the replacement will be either "single" or "end" depending on what the max value is.

In order to read from a file name that you put on the command line (i.e. in @ARGV) when you run the script, just remove DATA from while(<DATA>) (and leave off the __DATA__ section at the end) -- there's no need to explicitly open a file whose name is provided via @ARGV.